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