fork download
  1. #include <iostream>
  2. #include <type_traits>
  3. #include <memory>
  4. #include <string>
  5. #include <vector>
  6.  
  7. using namespace std;
  8.  
  9. template<typename T>
  10. struct move_on_copy
  11. {
  12. move_on_copy(T&& aValue) : value(move(aValue)) {}
  13. move_on_copy(const move_on_copy& other) : value(move(other.value)) {}
  14.  
  15. T& Value()
  16. {
  17. return value;
  18. }
  19.  
  20. const T& Value() const
  21. {
  22. return value;
  23. }
  24.  
  25. private:
  26. mutable T value;
  27. move_on_copy& operator=(move_on_copy&& aValue);
  28. move_on_copy& operator=(const move_on_copy& aValue);
  29. };
  30.  
  31.  
  32. template<typename T>
  33. auto make_move_on_copy(T&& aValue) -> typename enable_if<is_rvalue_reference<decltype(aValue)>::value, move_on_copy<T>>::type
  34. {
  35. return move_on_copy<T>(move(aValue));
  36. }
  37.  
  38. template<typename F>
  39. void invoke(F f)
  40. {
  41. f();
  42. }
  43.  
  44. // some trials
  45. int main()
  46. {
  47. unique_ptr<int> aPtr(new int(5));
  48. auto aPtrMov = make_move_on_copy(move(aPtr));
  49. unique_ptr<int> aPtr2(new int(5));
  50. auto aPtrMov2 = make_move_on_copy(move(aPtr2));
  51.  
  52. auto aPtrLam = [aPtrMov]
  53. {
  54. cout << "Ptr value: " << *(aPtrMov.Value()) << endl;
  55. };
  56.  
  57. auto aPtrMutableLam = [aPtrMov2] () mutable
  58. {
  59. (*aPtrMov2.Value())++;
  60. cout << "Ptr value: " << *(aPtrMov2.Value()) << endl;
  61. };
  62.  
  63. invoke(aPtrLam);
  64. invoke(aPtrMutableLam);
  65. invoke(aPtrMutableLam);
  66.  
  67.  
  68. return 0;
  69. }
Runtime error #stdin #stdout 0s 3060KB
stdin
Standard input is empty
stdout
Ptr value: 5
Ptr value: 6