|  | Home | Libraries | People | FAQ | More | 
Boost.Move is based on macros that are expanded to true rvalue references in C++0x compilers and emulated rvalue reference classes and conversion operators in C++03 compilers.
      In C++03 compilers Boost.Move defines a class
      named ::boost::rv:
    
template <class T> class rv : public T { rv(); ~rv(); rv(rv const&); void operator=(rv const&); };
      which is convertible to the movable base class (usual C++ derived to base conversion).
      When users mark their classes as BOOST_MOVABLE_BUT_NOT_COPYABLE
      or BOOST_COPYABLE_AND_MOVABLE,
      these macros define conversion operators to references to ::boost::rv:
    
#define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\ public:\ operator ::boost::rv<TYPE>&() \ { return *static_cast< ::boost::rv<TYPE>* >(this); }\ operator const ::boost::rv<TYPE>&() const \ { return static_cast<const ::boost::rv<TYPE>* >(this); }\ private:\ //More stuff...
      BOOST_MOVABLE_BUT_NOT_COPYABLE
      also declares a private copy constructor and assignment. BOOST_COPYABLE_AND_MOVABLE
      defines a non-const copy constructor TYPE
      &operator=(TYPE&)
      that forwards to a const version:
    
#define BOOST_COPYABLE_AND_MOVABLE(TYPE)\ public:\ TYPE& operator=(TYPE &t)\ { this->operator=(static_cast<const ::boost::rv<TYPE> &>(const_cast<const TYPE &>(t))); return *this;}\ //More stuff...
      In C++0x compilers BOOST_COPYABLE_AND_MOVABLE
      expands to nothing and BOOST_MOVABLE_BUT_NOT_COPYABLE
      declares copy constructor and assigment operator private.
    
      When users define the BOOST_RV_REF
      overload of a copy constructor/assignment, in C++0x compilers it is expanded
      to a rvalue reference (T&&)
      overload and in C++03 compilers it is expanded to a ::boost::rv<T>
      & overload:
    
#define BOOST_RV_REF(TYPE) ::boost::rv< TYPE >& \
      When users define the BOOST_COPY_ASSIGN_REF
      overload, it is expanded to a usual copy assignment (const
      T &)
      overload in C++0x compilers and to a const
      ::boost::rv &
      overload in C++03 compilers:
    
#define BOOST_COPY_ASSIGN_REF(TYPE) const ::boost::rv< TYPE >&
As seen, in Boost.Move generates efficient and clean code for C++0x move semantics, without modifying any resolution overload. For C++03 compilers when overload resolution is performed these are the bindings:
::boost::rv< TYPE >&
        const
          ::boost::rv< TYPE >&
        TYPE&
        
      The library does not define the equivalent of BOOST_COPY_ASSIGN_REF
      for copy construction (say, BOOST_COPY_CTOR_REF)
      because nearly all modern compilers implement RVO and this is much more efficient
      than any move emulation. move
      just casts TYPE &
      into ::boost::rv<TYPE> &.
    
      Here's an example that demostrates how different rlvalue objects bind to ::boost::rv references in the presence of three overloads
      and the conversion operators in C++03 compilers:
    
#include <boost/move/core.hpp> #include <iostream> class sink_tester { public: //conversions provided by BOOST_COPYABLE_AND_MOVABLE operator ::boost::rv<sink_tester>&() { return *static_cast< ::boost::rv<sink_tester>* >(this); } operator const ::boost::rv<sink_tester>&() const { return *static_cast<const ::boost::rv<sink_tester>* >(this); } }; //Functions returning different r/lvalue types sink_tester rvalue() { return sink_tester(); } const sink_tester const_rvalue() { return sink_tester(); } sink_tester & lvalue() { static sink_tester lv; return lv; } const sink_tester & const_lvalue() { static const sink_tester clv = sink_tester(); return clv; } //BOOST_RV_REF overload void sink(::boost::rv<sink_tester> &) { std::cout << "non-const rvalue catched" << std::endl; } //BOOST_COPY_ASSIGN_REF overload void sink(const ::boost::rv<sink_tester> &){ std::cout << "const (r-l)value catched" << std::endl; } //Overload provided by BOOST_COPYABLE_AND_MOVABLE void sink(sink_tester &) { std::cout << "non-const lvalue catched" << std::endl; } int main() { sink(const_rvalue()); //"const (r-l)value catched" sink(const_lvalue()); //"const (r-l)value catched" sink(lvalue()); //"non-const lvalue catched" sink(rvalue()); //"non-const rvalue catched" return 0; }