fork 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, 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. std::function<R()> mTarget;
  36. std::function<T(R)> mCallback;
  37. public:
  38. DelegateTemplate(R(*target)(Args...), T(*callback)(R), Args... args)
  39. : mTarget(std::bind(target, args...))
  40. , mCallback(callback)
  41. {
  42. }
  43.  
  44. template<class S>
  45. DelegateTemplate(R(S::*target)(Args...), S* obj, T(*callback)(R), Args... args)
  46. : mTarget(std::bind(target, obj, args...))
  47. , mCallback(callback)
  48. {
  49. }
  50.  
  51. ~DelegateTemplate() { }
  52.  
  53. void CallFunction() override
  54. {
  55. mCallback(mTarget());
  56. }
  57. };
  58.  
  59. int Foo1(int i)
  60. {
  61. std::cout << "Foo1.i = " << i << std::endl;
  62. return i;
  63. }
  64.  
  65. void Callback1(int i)
  66. {
  67. std::cout << "Callback1.i = " << i << std::endl;
  68. }
  69.  
  70. const char* Foo2(double r)
  71. {
  72. std::cout << "Foo2.r = " << r << std::endl;
  73. return "hello world";
  74. }
  75.  
  76. void Callback2(const char* str)
  77. {
  78. std::cout << "Callback1.str = " << str << std::endl;
  79. }
  80.  
  81. class Test
  82. {
  83. public:
  84. int Foo3(const char* str)
  85. {
  86. std::cout << "Test::Foo3.str = " << str << std::endl;
  87. return 4;
  88. }
  89. };
  90.  
  91. int Foo1Thrower(int i)
  92. {
  93. std::cout << "Foo1.i = " << i << std::endl;
  94. throw i;
  95. return i;
  96. }
  97.  
  98. int main()
  99. {
  100. Delegate d;
  101. d.RegisterFunction(&Foo1Thrower, &Callback1, 42);
  102. d.CallFunction();
  103. }
Runtime error #stdin #stdout #stderr 0s 3432KB
stdin
Standard input is empty
stdout
Foo1.i = 42
stderr
terminate called after throwing an instance of 'int'