![]() |
Home | Libraries | People | FAQ | More |
For movable classes 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_MOVE_NAMESPACE::rv<TYPE>&() \ { return *reinterpret_cast< ::BOOST_MOVE_NAMESPACE::rv<TYPE>* >(this); }\ operator const ::BOOST_MOVE_NAMESPACE::rv<TYPE>&() const \ { return *reinterpret_cast<const ::BOOST_MOVE_NAMESPACE::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...
When users define the BOOST_RV_REF
overload of a copy constructor/assignment, it is expanded to a ::boost::rv reference overload:
#define BOOST_RV_REF(TYPE) ::boost::rv< TYPE >& \
When users define the BOOST_COPY_ASSIGN_REF
overload, it is expanded to a const ::boost::rv
references overload (in the 'Optimized mode'):
#define BOOST_COPY_ASSIGN_REF(TYPE) const ::boost::rv< TYPE >&
Now 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:
#include <boost/move/move.hpp> #include <iostream> class sink_tester { public: //conversions provided by BOOST_COPYABLE_AND_MOVABLE operator ::boost::rv<sink_tester>&() { return *reinterpret_cast< ::boost::rv<sink_tester>* >(this); } operator const ::boost::rv<sink_tester>&() const { return *reinterpret_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; }
![]() |
Important |
|---|---|
For 'Non-optimized' emulation mode no | |