Boost logo

Boost :

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:
> [...]
> 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
     auto_any(T& t)
       : item(t)
    { }
    mutable T item;

template<typename T>
struct auto_any <T, true>: auto_any_base
     auto_any(T t)
       : item()
    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
swappable containers.

AFAIK, while detecting the presence of T::swap is possible [1],
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, gregod at, cpdaniel at, john at