From 73d71ba59cb26415ccd9f6c43e3450d9d7ffed46 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Sun, 13 Sep 2015 16:02:25 -0400 Subject: [PATCH] [tutorial] Document that some containers can hold references --- doc/tutorial.md | 37 +++++++++++++++++++++++++-------- example/tutorial/containers.cpp | 28 ++++++++++++++++++------- 2 files changed, 48 insertions(+), 17 deletions(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index 3f3a53aaef..37f4cf098d 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -1793,21 +1793,40 @@ and so on. @subsection tutorial-containers-elements Container elements -In Hana, containers own their elements. When a container is created, it makes -a _copy_ of the elements used to initialize it and stores them inside the -container. Of course, unnecessary copies are avoided by using move semantics. -Because of those owning semantics, the lifetime of the objects inside the -container is the same as that of the container. +In Hana, containers own their elements. When a container is created, it +normally makes a _copy_ of the elements used to initialize it and stores them +inside the container. Of course, unnecessary copies are avoided by using move +semantics. Because of those owning semantics, the lifetime of the objects +inside the container is the same as that of the container. @snippet example/tutorial/containers.cpp lifetime -Much like containers in the standard library, containers in Hana expect their -elements to be objects. For this reason, references _may not_ be stored in -them. When references must be stored inside a container, one should use a -`std::reference_wrapper` instead: +However, some containers allow storing references instead of actual objects. +In that case, the owning semantics explained above do not hold anymore. For +example, it is possible to create a `hana::tuple` holding references as +follows: + +@snippet example/tutorial/containers.cpp reference_tuple + +@note +Of course, a single tuple can also hold some elements by value and other +elements by reference. + +Since explicitly specifying the type of the container to achieve by-reference +semantics can be cumbersome (and sometimes downright impossible when that +type is implementation-defined), the `make_xxx` family of functions also +support the use of `reference_wrapper`s: @snippet example/tutorial/containers.cpp reference_wrapper +When passed to a `hana::make_xxx` function, `std::reference_wrapper`s and +`boost::reference_wrapper`s will cause the container to hold a reference +instead of a `reference_wrapper`. Of course, only the `make_xxx` functions +associated to containers that support holding references implement this +special behavior. To know whether a container is able to hold references +(and implements this behavior), one should consult the reference documentation +for that container. + diff --git a/example/tutorial/containers.cpp b/example/tutorial/containers.cpp index f59b3f73eb..b71c4bfabc 100644 --- a/example/tutorial/containers.cpp +++ b/example/tutorial/containers.cpp @@ -75,17 +75,29 @@ std::string& s = xs[0_c]; }{ +//! [reference_tuple] +std::string hello = "Hello"; +std::vector world = {'W', 'o', 'r', 'l', 'd'}; + +hana::tuple&> xs{hello, world}; + +// s is a reference to `hello` +std::string& s = xs[0_c]; +BOOST_HANA_RUNTIME_CHECK(&s == &hello); +//! [reference_tuple] + +}{ + //! [reference_wrapper] -std::vector ints = { /* huge vector of ints */ }; -std::vector strings = { /* huge vector of strings */ }; +std::string hello = "Hello"; +std::vector world = {'W', 'o', 'r', 'l', 'd'}; -auto map = hana::make_map( - hana::make_pair(hana::type_c, std::ref(ints)), - hana::make_pair(hana::type_c, std::ref(strings)) -); +auto xs = hana::make_tuple(std::ref(hello), std::ref(world)); -auto& v = map[hana::type_c].get(); -BOOST_HANA_RUNTIME_CHECK(&v == &ints); +std::string& hello_ref = xs[0_c]; +std::vector& world_ref = xs[1_c]; +BOOST_HANA_RUNTIME_CHECK(&hello_ref == &hello); +BOOST_HANA_RUNTIME_CHECK(&world_ref == &world); //! [reference_wrapper] }