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