
When an rvalue range is adapted in range-based for loop, the lifetime of the rvalue range ends before the loop body begins. For example, the following code produces dangling references. for (auto x : std::string("Hello world!") | reversed) { /*...*/ } This is the temporary range lifetime issue. When I proposed BOOST_FOREACH extension for this issue, ( http://lists.boost.org/Archives/boost/2011/04/180591.php ) a solution with "moving an rvalue range into range adaptors" was suggested in the thread. I implemented this approach as a range adaptor (with the aid of rvalue references and decltype C++11 features): for (auto x : std::string("Hello world!") | moved | reversed) { /*...*/ } When an rvalue range is piped to `moved` adaptor, it returns `moved_range`. `moved_range` stores the following data: * Moved rvalue range: The rvalue range is moved and stored in `moved_range`. * Applied adaptors: When range adaptors are applied to`moved_range`, they are not invoked immediately; they are stored in fusion vector. The stored adaptors are invoked when `begin` or `end` member functions of `moved_range` are called. (To prevent repeated applications of the stored range adaptors, begin and end iterators are cached when they are first computed.) For example, in `std::string("Hello world!") | moved | reversed`, 1. By applying `moved` adaptor, `moved_range` is created. It stores `std::string` object moved from `std::string("Hello world!")`. It doesn't store any adaptors. 2. By applying `reversed` adaptor, another `moved_range` is created. It stores `std::string` object moved from the previous `moved_range`. It also stores `reversed` adaptor in fusion vector. Step 2 is repeated if more adaptors are applied. Then, in "for-init-statement" of range-based for loop, the stored adaptors are actually applied (and the result is cached). The free function version (`boost::adaptors::move`) supports `std::initializer_list`: for (auto x : move( {1, 2, 3, 4, 5} ) | reversed) { /*...*/ } Note that we cannot support it in the pipe syntax `{1, 2, 3, 4, 5} | moved` because the C++11 Standard does not allow to use list initializers in binary operators. Code attached. Comments? Regards, Michel