
On Thu, Apr 22, 2010 at 11:43 AM, Robert Jones <robertgbjones@gmail.com>wrote:
I'm not able to use the latest Boost release, so I've plagarised some little bits that are useful, and in the process might have missed something, so bear with me.
I have this bit of code...
#include <algorithm> #include <boost/range.hpp>
template < class SinglePassRange, class UnaryFunction > UnaryFunction for_each( SinglePassRange & rng, UnaryFunction fun ) { return std::for_each( boost::begin( rng ), boost::end( rng ), fun ); }
struct A { }; void f( const A & );
std::vector< A > generateVec( );
int main( ) { for_each( generateVec( ), f ); }
which understandably fails to compile as I'm passing an lvalue as non-const reference. I can fix this by adding a const ref overload of for_each, but no such overload exists in the real boost range header (AFAIK).
Gosh this was unfortunate. The lack of a const overload existed only on the trunk (never the release branch) for a few days. This could not have been more wrong if I coloured it purple! You should indeed match the current trunk and the release branch by adding a const overload for_each.
Returning containers by value seems to be the 'right way' now, as RVO should sort out the copy elision.
I'm not convinced that this is the 'right way'. I find that for trivial examples the copy is optimized away, but that on many compilers at various levels of call depth the copy construction occurs causing a huge performance degradation. I suspect that the 'right way' is still by using references in C++03 and by using move constructors in C++0x.
What I'm doing in this code seems reasonable - should it be supported by const ref overloads, or have I missed some 'gotcha' somewhere?
You are not missing anything at all. The const overload should be there and will always be there in Boost.Range.
Thanks,
- Rob.
Sorry for any confusion and wasted time, Neil Groves