fork download
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. template< class T > struct my_remove_reference {typedef T type;};
  5. template< class T > struct my_remove_reference<T&> {typedef T type;};
  6. template< class T > struct my_remove_reference<T&&> {typedef T type;};
  7.  
  8. template <typename T>
  9. typename my_remove_reference<T>::type&& my_move(T&& arg)
  10. {
  11. return static_cast<typename my_remove_reference<T>::type&&>(arg);
  12. }
  13.  
  14. struct S
  15. {
  16. int *ptr = nullptr;
  17.  
  18. S() { cout << "S() default constructor, ptr = " << ptr << endl; }
  19. S(int *p) : ptr(p) { cout << "S(int*) constructor, ptr = " << ptr << endl; }
  20. };
  21.  
  22. class MoveTester
  23. {
  24. private:
  25. int *m_ptr = nullptr;
  26.  
  27. public:
  28. MoveTester() { cout << "MT() default constructor" << endl; }
  29. MoveTester(const MoveTester &) = delete;
  30. MoveTester(MoveTester&& src) : m_ptr(src.m_ptr) { src.m_ptr = nullptr; cout << "MT(MT&&) move constructor" << endl; }
  31.  
  32. MoveTester(int *ptr) : m_ptr(ptr) { cout << "MT(int*) constructor" << endl; }
  33. MoveTester(S&& src) : m_ptr(src.ptr) { src.ptr = nullptr; cout << "MT(S&&) move constructor" << endl; }
  34.  
  35. MoveTester& operator=(const MoveTester &) = delete;
  36. MoveTester& operator=(MoveTester&& rhs) { m_ptr = rhs.m_ptr; rhs.m_ptr = nullptr; cout << "MT::operator=(MT&&) move assignment" << endl; return *this; }
  37. MoveTester& operator=(int *rhs) { m_ptr = rhs; cout << "MT::operator=(int*) copy assignment" << endl; return *this; }
  38. MoveTester& operator=(S&& src) { m_ptr = src.ptr; src.ptr = nullptr; cout << "MT::operator=(S&&) move assignment" << endl; return *this; }
  39.  
  40. void display(const char *name) const { cout << name << ".m_ptr = " << m_ptr << endl; }
  41. };
  42.  
  43. int* int_to_ptr(intptr_t value) { return reinterpret_cast<int*>(value); }
  44.  
  45. int main()
  46. {
  47. cout << "MoveTester mt1;" << endl;
  48. MoveTester mt1;
  49. mt1.display("mt1");
  50.  
  51. cout << endl;
  52.  
  53. cout << "MoveTester mt2 = int_to_ptr(12345);" << endl;
  54. MoveTester mt2 = int_to_ptr(12345);
  55. mt2.display("mt2");
  56.  
  57. cout << endl;
  58.  
  59. //MoveTester mt3 = mt2; // compiler error! Copy constructor is deleted
  60. cout << "MoveTester mt3 = my_move(mt2);" << endl;
  61. MoveTester mt3 = my_move(mt2);
  62. mt2.display("mt2");
  63. mt3.display("mt3");
  64.  
  65. cout << endl;
  66.  
  67. cout << "MoveTester mt4 = S();" << endl;
  68. MoveTester mt4 = S();
  69. mt4.display("mt4");
  70.  
  71. cout << endl;
  72.  
  73. cout << "MoveTester mt5 = S(int_to_ptr(67890));" << endl;
  74. MoveTester mt5 = S(int_to_ptr(67890));
  75. mt5.display("mt5");
  76.  
  77. cout << endl;
  78.  
  79. //mt1 = mt5; // compiler error! Copy assignment is deleted
  80. cout << "mt1 = my_move(mt5);" << endl;
  81. mt1 = my_move(mt5);
  82. mt1.display("mt1");
  83. mt5.display("mt5");
  84.  
  85. cout << endl;
  86.  
  87. cout << "mt1 = int_to_ptr(13579);" << endl;
  88. mt1 = int_to_ptr(13579);
  89. mt1.display("mt1");
  90.  
  91. cout << endl;
  92.  
  93. cout << "mt1 = S();" << endl;
  94. mt1 = S();
  95. mt1.display("mt1");
  96.  
  97. cout << endl;
  98.  
  99. cout << "mt1 = S(int_to_ptr(24680));" << endl;
  100. mt1 = S(int_to_ptr(24680));
  101. mt1.display("mt1");
  102.  
  103. return 0;
  104. }
Success #stdin #stdout 0s 15240KB
stdin
Standard input is empty
stdout
MoveTester mt1;
MT() default constructor
mt1.m_ptr = 0

MoveTester mt2 = int_to_ptr(12345);
MT(int*) constructor
mt2.m_ptr = 0x3039

MoveTester mt3 = my_move(mt2);
MT(MT&&) move constructor
mt2.m_ptr = 0
mt3.m_ptr = 0x3039

MoveTester mt4 = S();
S() default constructor, ptr = 0
MT(S&&) move constructor
mt4.m_ptr = 0

MoveTester mt5 = S(int_to_ptr(67890));
S(int*) constructor, ptr = 0x10932
MT(S&&) move constructor
mt5.m_ptr = 0x10932

mt1 = my_move(mt5);
MT::operator=(MT&&) move assignment
mt1.m_ptr = 0x10932
mt5.m_ptr = 0

mt1 = int_to_ptr(13579);
MT::operator=(int*) copy assignment
mt1.m_ptr = 0x350b

mt1 = S();
S() default constructor, ptr = 0
MT::operator=(S&&) move assignment
mt1.m_ptr = 0

mt1 = S(int_to_ptr(24680));
S(int*) constructor, ptr = 0x6068
MT::operator=(S&&) move assignment
mt1.m_ptr = 0x6068