Boost logo

Boost :

Subject: Re: [boost] [Range] Range adaptor approach for temporary range lifetime issue
From: Michel Morin (mimomorin_at_[hidden])
Date: 2012-06-23 19:04:06

Nathan Ridge wrote:
>> > Here is an example of the manual approach:
>> >
>> > template <typename Range> void f(Range&&);
>> >
>> > // No lifetime problem.
>> > f(std::string("Hello world!") | reversed);
>> >
>> > // `moved` is not necessary.
>> > f(std::string("Hello world!") | moved | reversed);
>> >
>> > In the automatic approach, `std::string("Hello world!") | reversed` returns
>> > `moved_range<std::string, boost::fusion::vector<reverse_forwarder> >`.
>> As opposed to what? You haven't shown me what it returns in the manual approach.
> In the manual approach it would return the same thing it does now:
> reversed_range<std::string>.
> Basically, the "automatic approach" is having every adaptor automatically wrap
> the range in a moved_range *just in case* it's used in a context where it needs
> to be moved, and the "manual approach" is having a "moved" adaptor that does the
> wrapping and needs to be used explicitly in such contexts, while leaving other
> adaptors unchanged.
> The tradeoff is between moving the container in contexts where it doesn't have
> to be moved (where the temporary range's lifetime is long enough) vs. having
> to remember to add " | moved" in contexts where it does have to be moved.

Exactly right. Thanks for the explanation, Nate!

And here is a third option: "automatic approach with opt-out method".
This is just an "automatic approach", but an opt-out method is also provided.

    template <typename Range>
    inline Range const& dont_move(Range&& rng)
        return rng;

With this function, we can avoid the use of moved_range.

    f(std::string("Hello world!") | reversed); // Use moved_range
    f(dont_move(std::string("Hello world!")) | reversed); // Don't use


Boost list run by bdawes at, gregod at, cpdaniel at, john at