Boost logo

Boost :

Subject: Re: [boost] [variant] Basic rvalue and C++11 features support
From: Hartmut Kaiser (hartmut.kaiser_at_[hidden])
Date: 2013-01-08 09:18:51


> On Tue, Jan 8, 2013 at 2:49 AM, Hartmut Kaiser <hartmut.kaiser_at_[hidden]>
> wrote:
> >> On 1/8/13 4:14 AM, Paul Smith wrote:
> >> > A recursive_wrapper is not a pointer. It's a value-like wrapper
> >> > that is assumed to always contain a valid object. The move
> >> > constructor should leave the moved-from recursive_wrapper in a
> >> > valid state, which precludes nullifying it.
> >> > That is, unless you suggest adding an "empty" state to
> >> > recursive_wrapper, which doesn't sound like a very good idea.
> >>
> >> I disagree. That state will happen only when copying rvalues which
> >> will immediately be destructed anyway. What danger do you see in that
> >> situation? Example:
> >>
> >> recursive_wrapper<foo> bar() {...} // function returning
> >> recursive_wrapper
> >>
> >> recursive_wrapper<foo> foo(bar()); // copy
> >>
> >> Under no circumstances will anyone get to see that "empty" state.
> >> Do you see something that I don't?
> >>
> >> Without this move optimization (as it currently is), it is very
> >> inefficient especially with big structures (e.g. tuples and fusion
> >> adapted structs).
> >> Without this optimization, such temporary copies will end up with two
> >> heap allocations and unnecessary copying of the structures, instead
> >> of one heap allocation and a simple pointer swap. That would mean the
> >> missed optimization in the order of magnitudes with applications that
> >> use variant heavily (e.g. Spirit).
> >
> > I agree 100% with Joel. Move construction means move construction -
> > i.e. the source object is by definition left in a zombie state. No harm
> done.
> > What's the point in having a move constructor which essentially is
> > equivalent to a copy constructor in the first place?
>
> Because it's not equivalent to a copy constructor. I can mutate the source
> object, just not break it.

I did not suggest breaking the object. Setting the pointer to zero still
leaves the object in valid state, no?
And if not, it is easy enough to make it a valid state by changing the
implementation.

> The move-ctor of std::vector is much more
> efficient than the copy-ctor, even though it leaves the source as a
> completely valid vector. Even in the recursive_wrapper case, the move-ctor
> is still (potentially) more efficient than the copy-ctor.

The only thing the standard requires wrt a moved-from object is that they
are left in a valid (although unspecified) state. Thus simply nulling out
the pointer in the reference_wrapper should do the trick (just as Joel
proposed).

See for instance: 17.6.5.15 - [lib.types.movedfrom]

<quote>
Objects of types defined in the C++ standard library may be moved from
(12.8). Move operations may
be explicitly specified or implicitly generated. Unless otherwise specified,
such moved-from objects shall be
placed in a valid but unspecified state.
</quote>

Regards Hartmut
---------------
http://boost-spirit.com
http://stellar.cct.lsu.edu


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk