Skip to content

Commit cf327f5

Browse files
committed
[tutorial] Document that some containers can hold references
1 parent b1ae885 commit cf327f5

File tree

2 files changed

+48
-17
lines changed

2 files changed

+48
-17
lines changed

doc/tutorial.md

+28-9
Original file line numberDiff line numberDiff line change
@@ -1846,21 +1846,40 @@ and so on.
18461846

18471847
@subsection tutorial-containers-elements Container elements
18481848

1849-
In Hana, containers own their elements. When a container is created, it makes
1850-
a _copy_ of the elements used to initialize it and stores them inside the
1851-
container. Of course, unnecessary copies are avoided by using move semantics.
1852-
Because of those owning semantics, the lifetime of the objects inside the
1853-
container is the same as that of the container.
1849+
In Hana, containers own their elements. When a container is created, it
1850+
normally makes a _copy_ of the elements used to initialize it and stores them
1851+
inside the container. Of course, unnecessary copies are avoided by using move
1852+
semantics. Because of those owning semantics, the lifetime of the objects
1853+
inside the container is the same as that of the container.
18541854

18551855
@snippet example/tutorial/containers.cpp lifetime
18561856

1857-
Much like containers in the standard library, containers in Hana expect their
1858-
elements to be objects. For this reason, references _may not_ be stored in
1859-
them. When references must be stored inside a container, one should use a
1860-
`std::reference_wrapper` instead:
1857+
However, some containers allow storing references instead of actual objects.
1858+
In that case, the owning semantics explained above do not hold anymore. For
1859+
example, it is possible to create a `hana::tuple` holding references as
1860+
follows:
1861+
1862+
@snippet example/tutorial/containers.cpp reference_tuple
1863+
1864+
@note
1865+
Of course, a single tuple can also hold some elements by value and other
1866+
elements by reference.
1867+
1868+
Since explicitly specifying the type of the container to achieve by-reference
1869+
semantics can be cumbersome (and sometimes downright impossible when that
1870+
type is implementation-defined), the `make_xxx` family of functions also
1871+
support the use of `reference_wrapper`s:
18611872

18621873
@snippet example/tutorial/containers.cpp reference_wrapper
18631874

1875+
When passed to a `hana::make_xxx` function, `std::reference_wrapper`s and
1876+
`boost::reference_wrapper`s will cause the container to hold a reference
1877+
instead of a `reference_wrapper`. Of course, only the `make_xxx` functions
1878+
associated to containers that support holding references implement this
1879+
special behavior. To know whether a container is able to hold references
1880+
(and implements this behavior), one should consult the reference documentation
1881+
for that container.
1882+
18641883

18651884

18661885

example/tutorial/containers.cpp

+20-8
Original file line numberDiff line numberDiff line change
@@ -75,17 +75,29 @@ std::string& s = xs[0_c];
7575

7676
}{
7777

78+
//! [reference_tuple]
79+
std::string hello = "Hello";
80+
std::vector<char> world = {'W', 'o', 'r', 'l', 'd'};
81+
82+
hana::tuple<std::string&, std::vector<char>&> xs{hello, world};
83+
84+
// s is a reference to `hello`
85+
std::string& s = xs[0_c];
86+
BOOST_HANA_RUNTIME_CHECK(&s == &hello);
87+
//! [reference_tuple]
88+
89+
}{
90+
7891
//! [reference_wrapper]
79-
std::vector<int> ints = { /* huge vector of ints */ };
80-
std::vector<std::string> strings = { /* huge vector of strings */ };
92+
std::string hello = "Hello";
93+
std::vector<char> world = {'W', 'o', 'r', 'l', 'd'};
8194

82-
auto map = hana::make_map(
83-
hana::make_pair(hana::type_c<int>, std::ref(ints)),
84-
hana::make_pair(hana::type_c<std::string>, std::ref(strings))
85-
);
95+
auto xs = hana::make_tuple(std::ref(hello), std::ref(world));
8696

87-
auto& v = map[hana::type_c<int>].get();
88-
BOOST_HANA_RUNTIME_CHECK(&v == &ints);
97+
std::string& hello_ref = xs[0_c];
98+
std::vector<char>& world_ref = xs[1_c];
99+
BOOST_HANA_RUNTIME_CHECK(&hello_ref == &hello);
100+
BOOST_HANA_RUNTIME_CHECK(&world_ref == &world);
89101
//! [reference_wrapper]
90102

91103
}

0 commit comments

Comments
 (0)