Skip to content

Commit a7c50c5

Browse files
committed
[tutorial] Document that some containers can hold references
1 parent 1181df7 commit a7c50c5

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
@@ -1805,21 +1805,40 @@ and so on.
18051805

18061806
@subsection tutorial-containers-elements Container elements
18071807

1808-
In Hana, containers own their elements. When a container is created, it makes
1809-
a _copy_ of the elements used to initialize it and stores them inside the
1810-
container. Of course, unnecessary copies are avoided by using move semantics.
1811-
Because of those owning semantics, the lifetime of the objects inside the
1812-
container is the same as that of the container.
1808+
In Hana, containers own their elements. When a container is created, it
1809+
normally makes a _copy_ of the elements used to initialize it and stores them
1810+
inside the container. Of course, unnecessary copies are avoided by using move
1811+
semantics. Because of those owning semantics, the lifetime of the objects
1812+
inside the container is the same as that of the container.
18131813

18141814
@snippet example/tutorial/containers.cpp lifetime
18151815

1816-
Much like containers in the standard library, containers in Hana expect their
1817-
elements to be objects. For this reason, references _may not_ be stored in
1818-
them. When references must be stored inside a container, one should use a
1819-
`std::reference_wrapper` instead:
1816+
However, some containers allow storing references instead of actual objects.
1817+
In that case, the owning semantics explained above do not hold anymore. For
1818+
example, it is possible to create a `hana::tuple` holding references as
1819+
follows:
1820+
1821+
@snippet example/tutorial/containers.cpp reference_tuple
1822+
1823+
@note
1824+
Of course, a single tuple can also hold some elements by value and other
1825+
elements by reference.
1826+
1827+
Since explicitly specifying the type of the container to achieve by-reference
1828+
semantics can be cumbersome (and sometimes downright impossible when that
1829+
type is implementation-defined), the `make_xxx` family of functions also
1830+
support the use of `reference_wrapper`s:
18201831

18211832
@snippet example/tutorial/containers.cpp reference_wrapper
18221833

1834+
When passed to a `hana::make_xxx` function, `std::reference_wrapper`s and
1835+
`boost::reference_wrapper`s will cause the container to hold a reference
1836+
instead of a `reference_wrapper`. Of course, only the `make_xxx` functions
1837+
associated to containers that support holding references implement this
1838+
special behavior. To know whether a container is able to hold references
1839+
(and implements this behavior), one should consult the reference documentation
1840+
for that container.
1841+
18231842

18241843

18251844

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)