123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- //We need to declare:
- //
- //2 conversions: rv<T> & and const rv<T> &
- //1 rv<T> & constructor: move constructor
- //1 const rv<T> & constructor: copy constructor
- //1 T & constructor: copy constructor
- //
- //Optimization:
- //Since RVO is better than move-construction,
- //avoid copy constructor overloading.
- #include <boost/move/detail/config_begin.hpp>
- #include <boost/move/utility_core.hpp>
- #include <iostream>
- bool moved = false;
- class obj
- {
- BOOST_COPYABLE_AND_MOVABLE(obj)
- public:
- obj()
- {
- std::cout << "constructing obj" << "\n";
- }
- ~obj()
- {}
- obj(const obj &)
- {
- std::cout << "copy construct from const obj" << "\n";
- }
- // copy construct from movable object (non-const rvalue, explicitly moved lvalue)
- obj(BOOST_RV_REF(obj))
- {
- std::cout << "move construct from movable rvalue" << "\n";
- }
- obj& operator =(BOOST_COPY_ASSIGN_REF(obj))
- {
- std::cout << "copy assign from const obj" << "\n";
- return *this;
- }
- obj& operator =(BOOST_RV_REF(obj))
- {
- std::cout << "move assign from movable rvalue" << "\n";
- return *this;
- }
- };
- obj rvalue_func() { return obj(); }
- const obj const_rvalue_func() { return obj(); }
- obj& lvalue_func() { static obj o; return o; }
- const obj& const_lvalue_func() { static obj o; return o; }
- obj produce() { return obj(); }
- void consume(obj){}
- int main()
- {
- { consume(produce()); }
- { obj o = produce(); }
- { obj o(produce()); }
- {
- obj o1(rvalue_func());
- obj o2 = const_rvalue_func();
- obj o3 = lvalue_func();
- obj o4 = const_lvalue_func();
- // can't explicitly move temporaries
- //obj o5 = boost::move(rvalue_func());
- obj o5;
- //Maybe missed optimization: copied
- o5 = rvalue_func();
- //Explicit forward works OK and optimized
- o5 = boost::forward<obj>(rvalue_func());
- obj o7 = boost::move(lvalue_func());
- obj o8 = boost::move(const_lvalue_func());
- obj o;
- o = rvalue_func();
- o = const_rvalue_func();
- o = lvalue_func();
- o = const_lvalue_func();
- // can't explicitly move temporaries
- //o = boost::move(rvalue_func());
- o = boost::forward<obj>(rvalue_func());
- o = boost::move(const_rvalue_func());
- o = boost::move(lvalue_func());
- o = boost::move(const_lvalue_func());
- }
- return 0;
- }
- //We need to declare:
- //
- //2 conversions: rv<T> & and const rv<T> &
- //1 rv<T> & constructor: move constructor
- //1 const rv<T> & constructor: copy constructor
- //1 T & constructor: copy constructor
- #include <boost/move/detail/config_end.hpp>
|