
2013/11/7 Eric Niebler
I wrote an article describing the "fat" std::istream_iterator and how it can be slimmed down by giving it an owning istream_range[1]. I see there already is an istream_range in Boost.Range, but it suffers from the fat-iterator problem I describe there. Is there a compelling reason why the implementation of boost::istream_range shouldn't be changed to be more like the one I describe? Also, as a commented pointed out, the same problem exists for the filtered range and the transformed range, too.
The trick, of course, will be keeping intermediate temporary ranges alive long enough to avoid lifetime issues when we chain adaptors and assign the result to a local variable. I think a range library that's sensitive to the value category of range objects and makes copies of rvalue ranges would solve this problem. Thoughts?
Is it time for Boost.Range 3.0?
[1]: http://ericniebler.com/2013/11/07/input-iterators-vs-input-ranges
That reminds me of the question I asked years ago (no one answered): http://lists.boost.org/boost-users/2011/08/70121.php Surely all approaches have tradeoffs... About the lifetime problem, could it be solved(?) with the approach Fusion used? (i.e. the distinction between 'view' & 'sequence'). I'm willing to have a reusable range, rather than a disposable one. The problem of a disposable one also described in my question. And I wonder, if we could have 2-phase construction. phase 1: A lazy range builder w/o begin/end phase 2: A range w/ begin/end and probably do some work at construction, as Eric suggested. And there have to be a trait like: template<class Range> struct range_type { typedef Range& type; }; And specialized for those have 2 phases. To implement the algorithms: template<class Range> void some_algo(Range const& rng, ...) { typename range_type<Range const>::type r(rng); some_algo(begin(r), end(r), ...); } For range adaptors, they also store phase 1 object, and make the underlying phase 2 object on the fly. What do you think?