
On 5/25/2010 4:00 AM, Thomas Klimpel wrote:
Ion GaztaƱaga wrote: [...]
The problem is what should generic algorithms should expect from a class, because for an object in non-optimized mode, assignment from a rvalue might not by the best way to implement an algorithm, but the algorithm does not know that (and even this has consequences with exception guarantees, but this is another issue).
Yes, this is an interesting question. In my opinion, breaking move assignment from temporaries is worse than not reusing existing resources, so for me the non-optimized mode is the one that catches by value for BOOST_COPYABLE_AND_MOVABLE classes.
We could provide a macro that translates rvalues into emulated rvalue references (if movable) or const references (if not movable). Unfortunately, this kills by-value parameter optimizations in C++03 :/ -------- #ifndef BOOST_NO_RVALUE_REFERENCES #define BOOST_MOVE_RVALUE( Expr ) Expr #else // #ifndef BOOST_NO_RVALUE_REFERENCES #define BOOST_MOVE_RVALUE( Expr ) \ ::boost::detail_move_rvalue::move_rvalue( BOOST_EXPR_TYPE_TAG_OF( Expr ), Expr ) namespace boost { namespace detail_move_rvalue { template< class T > struct move_rvalue_result : add_reference< typename add_const< typename add_rvalue_reference<T>::type >::type > { }; template< class T > inline typename move_rvalue_result<T>::type move_rvalue(type_tag<T>, typename move_rvalue_result<T>::type x) { return static_cast< typename move_rvalue_result<T>::type >(x); } } // namespace detail_move_rvalue } // namespace boost #endif // #ifndef BOOST_NO_RVALUE_REFERENCES -------- where -------- #define BOOST_EXPR_TYPE_TAG_OF( Expr ) \ (false ? \ ::boost::detail_expr_type_tag_of::deduce( ( Expr ), ( Expr ) ) : \ ::boost::detail_expr_type_tag_of::inducer()) namespace boost { template< class T > struct type_tag { typedef T type; }; namespace detail_expr_type_tag_of { struct inducer { template< class T > operator type_tag<T>() const { return type_tag<T>(); } }; template< class T, class U > inline type_tag< T& > deduce(T&, U&) { return type_tag< T& >(); } template< class T, class U > inline type_tag< const T& > deduce(const T&, U&) { return type_tag< const T& >(); } template< class T > inline type_tag<T> deduce(const T&, ...) { return type_tag<T>(); } } // namespace detail_expr_type_tag_of } // namespace boost -------- - Jeff