fork(3) download
  1. #include <memory>
  2. #include <iostream>
  3. #include <functional>
  4.  
  5. template<class... Args>
  6. class DelegateTemplate;
  7.  
  8. class Delegate
  9. {
  10. std::unique_ptr<Delegate> mPtr;
  11. public:
  12. virtual ~Delegate() { }
  13.  
  14. template<class R, class T, class... Args>
  15. void RegisterFunction(R(*target)(Args...), T(*callback)(R), Args&&... args)
  16. {
  17. mPtr.reset(new DelegateTemplate<R(Args&&...), T(R)>(target, callback, std::forward<Args...>(args...)));
  18. }
  19. /*
  20.   template<class R, class S, class T, class... Args>
  21.   void RegisterFunction(R(S::*target)(Args...), S* obj, T(*callback)(R), Args... args)
  22.   {
  23.   mPtr.reset(new DelegateTemplate<R(Args...), T(R)>(target, obj, callback, args...));
  24.   }
  25. */
  26. virtual void CallFunction()
  27. {
  28. mPtr->CallFunction();
  29. }
  30. };
  31.  
  32. template<class R, class T, class... Args>
  33. class DelegateTemplate<R(Args&&...), T(R)> : public Delegate
  34. {
  35. typedef R target_result_type;
  36. typedef T callback_result_type;
  37. private:
  38. std::function<R()> mTarget;
  39. std::function<T(R)> mCallback;
  40. public:
  41. DelegateTemplate(R(*target)(Args...), T(*callback)(R), Args&&... args)
  42. : mTarget(std::bind(target, std::forward<Args...>(args...)))
  43. , mCallback(callback)
  44. {
  45. }
  46. /*
  47.   template<class S>
  48.   DelegateTemplate(R(S::*target)(Args...), S* obj, T(*callback)(R), Args... args)
  49.   : mTarget(std::bind(target, obj, args...))
  50.   , mCallback(callback)
  51.   {
  52.   }
  53. */
  54. ~DelegateTemplate() { }
  55.  
  56. void CallFunction() override
  57. {
  58. mCallback(mTarget());
  59. }
  60. };
  61.  
  62. int Foo1(int i)
  63. {
  64. std::cout << "Foo1.i = " << i << std::endl;
  65. return i;
  66. }
  67.  
  68. void Callback1(int i)
  69. {
  70. std::cout << "Callback1.i = " << i << std::endl;
  71. }
  72.  
  73. const char* Foo2(double r)
  74. {
  75. std::cout << "Foo2.r = " << r << std::endl;
  76. return "hello world";
  77. }
  78.  
  79. void Callback2(const char* str)
  80. {
  81. std::cout << "Callback1.str = " << str << std::endl;
  82. }
  83.  
  84. class Test
  85. {
  86. public:
  87. int Foo3(const char* str)
  88. {
  89. std::cout << "Test::Foo3.str = " << str << std::endl;
  90. return 4;
  91. }
  92. };
  93.  
  94. int main()
  95. {
  96. Delegate d;
  97. d.RegisterFunction(&Foo1, &Callback1, 42);
  98. d.CallFunction();
  99.  
  100.  
  101. double x = 500.100;
  102. d.RegisterFunction(&Foo2, &Callback2, 44.0);
  103. d.CallFunction();
  104. /*
  105.   Test test;
  106.   d.RegisterFunction(&Test::Foo3, &test, Callback1, "hello from main");
  107.   d.CallFunction();
  108. */
  109. }
Success #stdin #stdout 0s 3432KB
stdin
Standard input is empty
stdout
Foo1.i = 42
Callback1.i = 42
Foo2.r = 44
Callback1.str = hello world