fork download
  1. #include <functional>
  2. #include <iostream>
  3. #include <vector>
  4.  
  5. //////////////////////////////////////////////////////////////////////////////// MOVE_ON_COPY
  6.  
  7. template<typename T>
  8. struct move_on_copy
  9. {
  10. move_on_copy(T&& aValue) : value(move(aValue)) {}
  11. move_on_copy(const move_on_copy& other) : value(move(other.value)) {}
  12.  
  13. T& Value()
  14. {
  15. return value;
  16. }
  17.  
  18. const T& Value() const
  19. {
  20. return value;
  21. }
  22.  
  23. private:
  24. mutable T value;
  25. move_on_copy& operator=(move_on_copy&& aValue);
  26. move_on_copy& operator=(const move_on_copy& aValue);
  27. };
  28.  
  29.  
  30. template <typename T>
  31. move_on_copy<typename std::remove_reference<T>::type> make_move_on_copy_wrapper_internal(typename std::remove_reference<T>::type&& aValue)
  32. {
  33. return move_on_copy<typename std::remove_reference<T>::type>(std::move(aValue));
  34. }
  35.  
  36. template <typename T>
  37. move_on_copy<T> make_move_on_copy_wrapper(T&& aValue)
  38. {
  39. return make_move_on_copy_wrapper_internal<T>(std::forward<T>(aValue));
  40. }
  41.  
  42. //////////////////////////////////////////////////////////////////////////////// MOVE_ON_COPY
  43.  
  44. template<typename T>
  45. struct mfunction;
  46.  
  47. template<class ReturnType, typename... ParamType>
  48. struct mfunction<ReturnType(ParamType...)> : public std::function<ReturnType(ParamType...)>
  49. {
  50. typedef std::function<ReturnType(ParamType...)> FnType;
  51.  
  52. mfunction() : FnType()
  53. {}
  54.  
  55. template<typename T>
  56. explicit mfunction(T&& fn) : FnType(std::forward<T>(fn))
  57. {}
  58.  
  59. mfunction(mfunction&& other) : FnType(move(static_cast<FnType&&>(other)))
  60. {}
  61.  
  62. mfunction& operator=(mfunction&& other)
  63. {
  64. FnType::operator=(move(static_cast<FnType&&>(other)));
  65. return *this;
  66. }
  67.  
  68. mfunction(const mfunction&) = delete;
  69. mfunction& operator=(const mfunction&) = delete;
  70. };
  71.  
  72. // examples
  73.  
  74. using namespace std;
  75.  
  76. struct ToCapture
  77. {
  78. ToCapture() {}
  79. ToCapture(ToCapture const&) { cout << "copied!" << endl; }
  80. ToCapture(ToCapture&&) { cout << "moved!" << endl; }
  81. };
  82.  
  83. void myFunction()
  84. {
  85. cout << "myFunction" << endl;
  86. }
  87.  
  88.  
  89. mfunction<void()> Create()
  90. {
  91. vector<int> vec {1,2,3};
  92. auto wrap = make_move_on_copy_wrapper(move(vec));
  93. mfunction<void()> f([wrap](){ cout << wrap.Value().size() << endl; });
  94. return f;
  95. }
  96.  
  97. int use_m_function_as_std_function(function<int(int, int)>& f)
  98. {
  99. return f(10,20);
  100. }
  101.  
  102. int main()
  103. {
  104. //1) creation
  105. ToCapture toCapt;
  106. // from lambda
  107. mfunction<void(int, string)> mfunction_1 ( [toCapt] (int i, string s) { cout << s << " " << i << endl;} );
  108. mfunction_1(1, "Hello");
  109. // from function pointer
  110. mfunction<void()> m_function_2 (&myFunction);
  111. m_function_2();
  112. // from std::function
  113. std::function<void(int)> stdFunc1 ([toCapt](int) {});
  114. cout << "---stdFunc1 created---" << endl;
  115. mfunction<void(int)> m_function3 (stdFunc1);
  116. stdFunc1(1);
  117. m_function3(1);
  118.  
  119. //2) noncopyability
  120. // auto mfunction_2 = mfunction_1;
  121. auto mfunction_2 = move(mfunction_1);
  122. //mfunction_2 = [](int,string){};
  123. //m_function_2 = mfunction_1;
  124.  
  125. //3) using
  126. auto mfunction_3 = Create();
  127. mfunction_3();
  128. mfunction<int(int,int)> mfunction_4([](int a, int b){ return a+b; });
  129. cout << use_m_function_as_std_function(mfunction_4) << endl;
  130.  
  131. return 0;
  132. }
Success #stdin #stdout 0s 3024KB
stdin
Standard input is empty
stdout
copied!
moved!
moved!
Hello 1
myFunction
copied!
moved!
---stdFunc1 created---
copied!
3
30