Boost logo

Boost :

Subject: Re: [boost] [move] moving temporaries of copyable types
From: Ion Gaztañaga (igaztanaga_at_[hidden])
Date: 2009-08-07 02:48:31


klaus triendl escribió:
> Ion Gaztañaga schrieb:
>> klaus triendl wrote:
>> > So, my question is whether this is well-known and this feature was
>>> deliberately excluded from Boost.Move or nobody has discovered it yet.
>>> It would be great to have support for copy- and (implicit)
>>> move-semantics.

Hi,

Sorry for the looong delay, but I've just fond time to investigate it
these days. In short, your approach is viable at least using MSVC 8&9,
Intel 9.0 (so I suppose it will work on any EDG frontend compiler) and
gcc 4.3 (I haven't tested other gcc compilers). Sadly, MSVC-7.1 has some
problems when forwarding types with const rv<T> & in copy constructors
and overall the need of an ifndef is quite ugly but I can't find any
workaround (if only we had constructing forwarding...)

Trying to write something portable, copyable and movable types can
be written like this:

class copymovable
{
    public:
    BOOST_ENABLE_MOVE_EMULATION(copymovable)

    //Copy constructor and assignment.
    //BOOST_COPY_REF is expanded to 'const rv<T> &' in c++98,
    //and to 'const T &' in C++0x
    copymovable(BOOST_COPY_REF(copymovable) o){}
    copymovable & operator=(BOOST_COPY_REF(copymovable) o) {}

    //Move constructor and assignment.
    //BOOST_RV_REF is expanded to 'rv<T> &' in c++98,
    //and to 'T &&' in C++0x
    copymovable(BOOST_RV_REF(copymovable) o)
    copymovable & operator=(BOOST_RV_REF(copymovable) o) {}

    //Additional copy constructor and assignment for c++98
    //compilers
    #ifndef BOOST_HAS_RVALUE_REFS
    copymovable(copymovable &o)
    copymovable & operator= (copymovable & o) {}
    #endif
};

The additional assignment could be produced with a macro forwarding to
the other constructor but the additional copy constructor can't
generated and that's a pity. As you discovered, I've checked that this
approach allows moving temporaries of copyable values:

copymovable produce();

copymovable cm;
//...

//Moved, not copied
cm = produce();

To sump up, this approach allows moving from non-const rvalues but
discards Visual 7.1 (I don't know if this should be still supported,
though) and syntax is much uglier. I think this should be discussed in
the mailing list before any proposal is presented for review.

If container writers want to support also catching temporary copymovable
types they should write also 3 versions (or catch it by value):

void push_back(BOOST_COPY_REF(T) t);
void push_back(BOOST_RV_REF(T) t);
#ifdef BOOST_HAS_RVALUE_REFS
void push_back(T &t);
#endif

Thanks a lot for your help and patience!

Ion


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