1 //We need to declare: 2 // 3 //2 conversions: rv<T> & and const rv<T> & 4 //1 rv<T> & constructor: move constructor 5 //1 const rv<T> & constructor: copy constructor 6 //1 T & constructor: copy constructor 7 // 8 //Optimization: 9 //Since RVO is better than move-construction, 10 //avoid copy constructor overloading. 11 #include <boost/move/detail/config_begin.hpp> 12 #include <boost/move/utility_core.hpp> 13 #include <iostream> 14 15 bool moved = false; 16 17 class obj 18 { 19 BOOST_COPYABLE_AND_MOVABLE(obj) 20 public: 21 obj()22 obj() 23 { 24 std::cout << "constructing obj" << "\n"; 25 } 26 ~obj()27 ~obj() 28 {} 29 obj(const obj &)30 obj(const obj &) 31 { 32 std::cout << "copy construct from const obj" << "\n"; 33 } 34 35 // copy construct from movable object (non-const rvalue, explicitly moved lvalue) obj(BOOST_RV_REF (obj))36 obj(BOOST_RV_REF(obj)) 37 { 38 std::cout << "move construct from movable rvalue" << "\n"; 39 } 40 operator =(BOOST_COPY_ASSIGN_REF (obj))41 obj& operator =(BOOST_COPY_ASSIGN_REF(obj)) 42 { 43 std::cout << "copy assign from const obj" << "\n"; 44 return *this; 45 } 46 operator =(BOOST_RV_REF (obj))47 obj& operator =(BOOST_RV_REF(obj)) 48 { 49 std::cout << "move assign from movable rvalue" << "\n"; 50 return *this; 51 } 52 }; 53 54 rvalue_func()55obj rvalue_func() { return obj(); } const_rvalue_func()56const obj const_rvalue_func() { return obj(); } lvalue_func()57obj& lvalue_func() { static obj o; return o; } const_lvalue_func()58const obj& const_lvalue_func() { static obj o; return o; } 59 produce()60obj produce() { return obj(); } 61 consume(obj)62void consume(obj){} 63 main()64int main() 65 { 66 { consume(produce()); } 67 { obj o = produce(); } 68 { obj o(produce()); } 69 { 70 obj o1(rvalue_func()); 71 obj o2 = const_rvalue_func(); 72 obj o3 = lvalue_func(); 73 obj o4 = const_lvalue_func(); 74 // can't explicitly move temporaries 75 //obj o5 = boost::move(rvalue_func()); 76 obj o5; 77 //Maybe missed optimization: copied 78 o5 = rvalue_func(); 79 //Explicit forward works OK and optimized 80 o5 = boost::forward<obj>(rvalue_func()); 81 82 obj o7 = boost::move(lvalue_func()); 83 obj o8 = boost::move(const_lvalue_func()); 84 85 obj o; 86 o = rvalue_func(); 87 o = const_rvalue_func(); 88 o = lvalue_func(); 89 o = const_lvalue_func(); 90 // can't explicitly move temporaries 91 //o = boost::move(rvalue_func()); 92 o = boost::forward<obj>(rvalue_func()); 93 o = boost::move(const_rvalue_func()); 94 o = boost::move(lvalue_func()); 95 o = boost::move(const_lvalue_func()); 96 } 97 return 0; 98 } 99 100 //We need to declare: 101 // 102 //2 conversions: rv<T> & and const rv<T> & 103 //1 rv<T> & constructor: move constructor 104 //1 const rv<T> & constructor: copy constructor 105 //1 T & constructor: copy constructor 106 107 #include <boost/move/detail/config_end.hpp> 108