Boost logo

Boost Users :

Subject: Re: [Boost-users] returning range adaptor generator
From: Nathan Ridge (zeratul976_at_[hidden])
Date: 2013-10-01 22:53:20


> Thanks. But the question is not really about one single adaptor that > indirected is. That was just an example (although your answer was > useful, thank you) > > How about in general? Say, > > template<class Range> > xxx getPuffedRange( Range& r ) { return r | indirected | > filtered(puff) | etc; } Your options are: 1) Use the exact type of the adapted range:      template <class Range>      filtered_range<PuffT, indirected_range<Range>> getPuffedRange(Range& r)      {          return r | indirected | filtered(puff);      }    In C++11 you can make this nicer by using decltype() and late-specified    return types:      template <class Range>      auto getPuffedRange(Range& r) -> decltype(r | indirected | filtered(puff))      {          return r | indirected | filtered(puff);      }    In C++14 you can make this even nicer by using return type deduction:      template <class Range>      auto getPuffedRange(Range& r)      {          return r | indirected | filtered(puff);      }      2) Use type erasure to erase everything about the range besides its value type:      template <class Range>      TypeErasedRange<E> getPuffedRange(Range& r)      {          return r | indirected | filtered(puff);      }    (where E is the element type of the returned range, which in this case would    be range_value<Range>::type, but could be something else if you have different    adaptors).    You can do this using Boost.Range's any_range [1], or roll your own type    erasure using Boost.TypeErasure [2] (or manually). 3) Eagerly populate a container like vector and return that:      template <class Range>      vector<E> getPuffedRange(Range& r)      {          vector<E> result;          push_back(result, r | indirected | filtered(puff));          return result;      }    (where again E is the element type of the returned range). Obviously there are tradeoffs between these three approaches:   (1) incurs no runtime penalty but it's clumsy to write.   (2) incurs a virtual function call to every iterator operation       on the type-erased range   (3) loses the laziness that range adaptors give you Regards, Nate    [1] http://www.boost.org/doc/libs/1_54_0/libs/range/doc/html/range/reference/ranges/any_range.html [2] http://www.boost.org/doc/libs/1_54_0/doc/html/boost_typeerasure.html


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net