Skip to content

Commit ff0fb7f

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

File tree

2 files changed

+48
-17
lines changed

2 files changed

+48
-17
lines changed

doc/tutorial.hpp

+28-9
Original file line numberDiff line numberDiff line change
@@ -1870,21 +1870,40 @@ and so on.
18701870
18711871
@subsection tutorial-containers-elements Container elements
18721872
1873-
In Hana, containers own their elements. When a container is created, it makes
1874-
a _copy_ of the elements used to initialize it and stores them inside the
1875-
container. Of course, unnecessary copies are avoided by using move semantics.
1876-
Because of those owning semantics, the lifetime of the objects inside the
1877-
container is the same as that of the container.
1873+
In Hana, containers own their elements. When a container is created, it
1874+
normally makes a _copy_ of the elements used to initialize it and stores them
1875+
inside the container. Of course, unnecessary copies are avoided by using move
1876+
semantics. Because of those owning semantics, the lifetime of the objects
1877+
inside the container is the same as that of the container.
18781878
18791879
@snippet example/tutorial/containers.cpp lifetime
18801880
1881-
Much like containers in the standard library, containers in Hana expect their
1882-
elements to be objects. For this reason, references _may not_ be stored in
1883-
them. When references must be stored inside a container, one should use a
1884-
`std::reference_wrapper` instead:
1881+
However, some containers allow storing references instead of actual objects.
1882+
In that case, the owning semantics explained above do not hold anymore. For
1883+
example, it is possible to create a `hana::tuple` holding references as
1884+
follows:
1885+
1886+
@snippet example/tutorial/containers.cpp reference_tuple
1887+
1888+
@note
1889+
Of course, a single tuple can also hold some elements by value and other
1890+
elements by reference.
1891+
1892+
Since explicitly specifying the type of the container to achieve by-reference
1893+
semantics can be cumbersome (and sometimes downright impossible when that
1894+
type is implementation-defined), the `make_xxx` family of functions also
1895+
support the use of `reference_wrapper`s:
18851896
18861897
@snippet example/tutorial/containers.cpp reference_wrapper
18871898
1899+
When passed to a `hana::make_xxx` function, `std::reference_wrapper`s and
1900+
`boost::reference_wrapper`s will cause the container to hold a reference
1901+
instead of a `reference_wrapper`. Of course, only the `make_xxx` functions
1902+
associated to containers that support holding references implement this
1903+
special behavior. To know whether a container is able to hold references
1904+
(and implements this behavior), one should consult the reference documentation
1905+
for that container.
1906+
18881907
18891908
18901909

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)