
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. 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 #if ! defined BOOST_NO_RVALUE_REFERENCES #define BOOST_MOVE(RVALUE) RVALUE #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. 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 https://svn.boost.org/trac/boost/ticket/6222), 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? Best, Vicente ///////////////////////////// class MoveOnly { #ifndef BOOST_NO_DELETED_FUNCTIONS public: MoveOnly(const MoveOnly&)=delete; MoveOnly& operator=(MoveOnly const&); #else private: MoveOnly(MoveOnly&); MoveOnly& operator=(MoveOnly&); public: #endif MoveOnly() { } #ifndef BOOST_NO_RVALUE_REFERENCES MoveOnly(MoveOnly&&) {} #else #if defined BOOST_THREAD_USES_MOVE MoveOnly(boost::rv<MoveOnly>&) {} MoveOnly& operator=(boost::rv<MoveOnly>&) { return *this; } operator ::boost::rv<MoveOnly>&() { return *static_cast< ::boost::rv<MoveOnly>* >(this); } operator const ::boost::rv<MoveOnly>&() const { return *static_cast<const ::boost::rv<MoveOnly>* >(this); } ::boost::rv<MoveOnly>& move() { return *static_cast< ::boost::rv<MoveOnly>* >(this); } const ::boost::rv<MoveOnly>& move() const { return *static_cast<const ::boost::rv<MoveOnly>* >(this); } #else #error #endif #endif void operator()() { } };