|
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
moved_range
Regards,
Michel
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk