copy_move_optimization.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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. bool moved = false;
  15. class obj
  16. {
  17. BOOST_COPYABLE_AND_MOVABLE(obj)
  18. public:
  19. obj()
  20. {
  21. std::cout << "constructing obj" << "\n";
  22. }
  23. ~obj()
  24. {}
  25. obj(const obj &)
  26. {
  27. std::cout << "copy construct from const obj" << "\n";
  28. }
  29. // copy construct from movable object (non-const rvalue, explicitly moved lvalue)
  30. obj(BOOST_RV_REF(obj))
  31. {
  32. std::cout << "move construct from movable rvalue" << "\n";
  33. }
  34. obj& operator =(BOOST_COPY_ASSIGN_REF(obj))
  35. {
  36. std::cout << "copy assign from const obj" << "\n";
  37. return *this;
  38. }
  39. obj& operator =(BOOST_RV_REF(obj))
  40. {
  41. std::cout << "move assign from movable rvalue" << "\n";
  42. return *this;
  43. }
  44. };
  45. obj rvalue_func() { return obj(); }
  46. const obj const_rvalue_func() { return obj(); }
  47. obj& lvalue_func() { static obj o; return o; }
  48. const obj& const_lvalue_func() { static obj o; return o; }
  49. obj produce() { return obj(); }
  50. void consume(obj){}
  51. int main()
  52. {
  53. { consume(produce()); }
  54. { obj o = produce(); }
  55. { obj o(produce()); }
  56. {
  57. obj o1(rvalue_func());
  58. obj o2 = const_rvalue_func();
  59. obj o3 = lvalue_func();
  60. obj o4 = const_lvalue_func();
  61. // can't explicitly move temporaries
  62. //obj o5 = boost::move(rvalue_func());
  63. obj o5;
  64. //Maybe missed optimization: copied
  65. o5 = rvalue_func();
  66. //Explicit forward works OK and optimized
  67. o5 = boost::forward<obj>(rvalue_func());
  68. obj o7 = boost::move(lvalue_func());
  69. obj o8 = boost::move(const_lvalue_func());
  70. obj o;
  71. o = rvalue_func();
  72. o = const_rvalue_func();
  73. o = lvalue_func();
  74. o = const_lvalue_func();
  75. // can't explicitly move temporaries
  76. //o = boost::move(rvalue_func());
  77. o = boost::forward<obj>(rvalue_func());
  78. o = boost::move(const_rvalue_func());
  79. o = boost::move(lvalue_func());
  80. o = boost::move(const_lvalue_func());
  81. }
  82. return 0;
  83. }
  84. //We need to declare:
  85. //
  86. //2 conversions: rv<T> & and const rv<T> &
  87. //1 rv<T> & constructor: move constructor
  88. //1 const rv<T> & constructor: copy constructor
  89. //1 T & constructor: copy constructor
  90. #include <boost/move/detail/config_end.hpp>