From: Giovanni Piero Deretta (gpderetta_at_[hidden])
Date: 2007-07-06 14:00:14
On 7/6/07, Lewis Hyatt <lhyatt_at_[hidden]> wrote:
> > Let me be more precise: using BOOST_FOREACH *with rvalue containers*
> > requires one "extra" copy. When the container is an lvalue, no copies
> > are made, ever. You suggested binding the rvalue to a const reference.
> > That would work, if you knew both that the object was an rvalue *and*
> > what the type of the object was. But you don't. Instead, you have to put
> > the object in a variant of sorts, and store a const reference to that.
> > That's where the extra copy comes from.
> > For all the details, see: http://www.artima.com/cppsource/foreach.html
> I guess, once the auto keyword is
> available, then you could probably avoid the copy, although you might
> have to make two macros, one that allows the container to be altered,
> and one that doesn't, or something like that.
BTW, couldn't BOOST_FOREACH internally detect if the container has a
swap member function and swap the container instead of copying it:
[here I assume that auto_any constructor is the source of the extra
copy, but I'm not 100% sure]
template<typename T, bool IsSwappable>
struct auto_any : auto_any_base
mutable T item;
struct auto_any <T, true>: auto_any_base
mutable T item;
The tricky part here is that this assumes that swap
does the obvious thing and T is default constructible.
The former is a sensible thing to expect from a container,
I'm not convinced of the latter. OTOH, this might work for non copyable but
AFAIK, while detecting the presence of T::swap is possible ,
detecting default constructibility isn't.
> Anyway, I guess this isn't
> such a big issue, because if copying a container is too expensive, you
> probably shouldn't be returning it from functions anyway...
I think that today, with NRVO widely implemented, this is no longer a problem.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk