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 | |
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 | |
22 | obj() |
23 | { |
24 | std::cout << "constructing obj"<< "\n"; |
25 | } |
26 | |
27 | ~obj() |
28 | {} |
29 | |
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) |
36 | obj(BOOST_RV_REF(obj)) |
37 | { |
38 | std::cout << "move construct from movable rvalue"<< "\n"; |
39 | } |
40 | |
41 | obj& operator =(BOOST_COPY_ASSIGN_REF(obj)) |
42 | { |
43 | std::cout << "copy assign from const obj"<< "\n"; |
44 | return *this; |
45 | } |
46 | |
47 | obj& operator =(BOOST_RV_REF(obj)) |
48 | { |
49 | std::cout << "move assign from movable rvalue"<< "\n"; |
50 | return *this; |
51 | } |
52 | }; |
53 | |
54 | |
55 | obj rvalue_func() { return obj(); } |
56 | const obj const_rvalue_func() { return obj(); } |
57 | obj& lvalue_func() { static obj o; return o; } |
58 | const obj& const_lvalue_func() { static obj o; return o; } |
59 | |
60 | obj produce() { return obj(); } |
61 | |
62 | void consume(obj){} |
63 | |
64 | int 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>(t: rvalue_func()); |
81 | |
82 | obj o7 = boost::move(t&: lvalue_func()); |
83 | obj o8 = boost::move(t: 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>(t: rvalue_func()); |
93 | o = boost::move(t: const_rvalue_func()); |
94 | o = boost::move(t&: lvalue_func()); |
95 | o = boost::move(t: 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 |