Skip to content

Commit 73d71ba

Browse files
committed
[tutorial] Document that some containers can hold references
1 parent 5e1280e commit 73d71ba

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

17941794
@subsection tutorial-containers-elements Container elements
17951795

1796-
In Hana, containers own their elements. When a container is created, it makes
1797-
a _copy_ of the elements used to initialize it and stores them inside the
1798-
container. Of course, unnecessary copies are avoided by using move semantics.
1799-
Because of those owning semantics, the lifetime of the objects inside the
1800-
container is the same as that of the container.
1796+
In Hana, containers own their elements. When a container is created, it
1797+
normally makes a _copy_ of the elements used to initialize it and stores them
1798+
inside the container. Of course, unnecessary copies are avoided by using move
1799+
semantics. Because of those owning semantics, the lifetime of the objects
1800+
inside the container is the same as that of the container.
18011801

18021802
@snippet example/tutorial/containers.cpp lifetime
18031803

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

18091820
@snippet example/tutorial/containers.cpp reference_wrapper
18101821

1822+
When passed to a `hana::make_xxx` function, `std::reference_wrapper`s and
1823+
`boost::reference_wrapper`s will cause the container to hold a reference
1824+
instead of a `reference_wrapper`. Of course, only the `make_xxx` functions
1825+
associated to containers that support holding references implement this
1826+
special behavior. To know whether a container is able to hold references
1827+
(and implements this behavior), one should consult the reference documentation
1828+
for that container.
1829+
18111830

18121831

18131832

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)