Boost logo

Boost :

Subject: Re: [boost] [move] explicit moving from a rvalue
From: Jeffrey Lee Hellrung, Jr. (jeffrey.hellrung_at_[hidden])
Date: 2012-03-27 11:01:24

On Mon, Mar 26, 2012 at 12:42 PM, Vicente J. Botet Escriba <
vicente.botet_at_[hidden]> wrote:

> Hi Ion,
> With the current emulation of move semantics of Boost.Thread using
> Boost.move, I have a case that I would like to make working in a portable
> way
> boost::thread t = boost::thread( MoveOnly());
> The library declares the template move constructor from a movable callable
> as as follows
> template <class F>
> explicit thread(boost::rv<F>& f);
> and MoveOnly is declared as defined below.
> The problem is a know limitation as the compiler is unable to deduce F as
> been MoveOnly even if MoveOnly is convertible to boost::rv<MoveOnly>&
> Jeffrey Lee Hellrung, Jr. made a proposal to try to solve the issue, but
> his proposal has a performance penality.

Agreed, although I would think a sufficiently advanced and aggressive
compiler could optimize the type erasure away.

Here it is a less elegant but efficient enough alternative. The addition of
> a explicit move conversion as
> ::boost::rv<MoveOnly>& move()
> {
> return *static_cast< ::boost::rv<MoveOnly>* >(this);
> }
> allows to the following to work as expected
> boost::thread t = boost::thread( MoveOnly().move());
> While this workaround works when we are using the emulation it doesn't
> works when rvalue references are supported.
> I have defined a macro BOOST_EXPLICIT_MOVE that allows to write portable
> code
> #else
> #define BOOST_MOVE(RVALUE) RVALUE.move()
> #endif
> that can be used as
> boost::thread t = boost::thread( BOOST_MOVE(MoveOnly()));
> The move() function is not really needed as the macro can hide the needed
> conversion, but could be preferred by users that don't need to make
> portable programs.

I played around with such a macro (essentially wrapping the argument in an
explicit cast if it was an rvalue of move-emulation-enabled type), but
haven't used it extensively. Hiding everything behind the macro
implementation, I think, is preferable to adding to the move emulation
interface. In any case, I question whether use of such a macro will catch
on. It's...ugly :/

> The evident liability is of course the use of the macro. Is there
> something wrong on this design, something to to improve?
> The same design can be used on compilers, such as as SunStudio (see
> that prefer the overload of a private copy constructor to an public move
> constructor. On these kind of compilers the following overload
> private:
> MoveOnly(MoveOnly&);
> public
> MoveOnly(boost::rv<MoveOnly>&)
> makes the following to fail at compile time
> MoveOnly MakeMoveOnly() {
> return MoveOnly();
> }
> but
> MoveOnly( MakeMoveOnly(() {
> return BOOST_MOVE(MoveOnly());
> }
> will work.
> Do you think that member functions as the explicit move() and a macro as
> BOOST_MOVE can be added to Boost.Move emulation?

The macro sounds plausible to me; I'm not convinced of the need for the
move member function.

> Vicente
> /////////////////////////////

- Jeff

Boost list run by bdawes at, gregod at, cpdaniel at, john at