fork download
  1. #include <boost/scoped_ptr.hpp>
  2. #include <boost/function.hpp>
  3. #include <algorithm>
  4. #include <iostream>
  5. #include <typeinfo>
  6. #include <ostream>
  7. #include <vector>
  8. #include <string>
  9.  
  10. using namespace std;
  11. using namespace boost;
  12.  
  13. typedef int KeyEvent;
  14. typedef function<void (const KeyEvent &)> KeyCallback;
  15.  
  16. struct AbstractCallback
  17. {
  18. virtual bool equals(const KeyCallback &f) const=0;
  19. virtual ~AbstractCallback(){}
  20. };
  21.  
  22. template<typename Callback>
  23. struct ConcreteCallback : AbstractCallback
  24. {
  25. const Callback &callback;
  26. explicit ConcreteCallback(const Callback &p_callback) : callback(p_callback) {}
  27. virtual bool equals(const KeyCallback &f) const
  28. {
  29. return callback == f;
  30. }
  31. };
  32.  
  33. struct KeyCallbackChecker
  34. {
  35. scoped_ptr<AbstractCallback> func;
  36. public:
  37. template<typename Func>
  38. KeyCallbackChecker(const Func &f) : func(new ConcreteCallback<Func>(f)) {}
  39. friend bool operator==(const KeyCallback &lhs,const KeyCallbackChecker &rhs)
  40. {
  41. return rhs.func->equals(lhs);
  42. }
  43. friend bool operator==(const KeyCallbackChecker &lhs,const KeyCallback &rhs)
  44. {
  45. return rhs==lhs;
  46. }
  47. };
  48.  
  49. void func1(const KeyEvent &)
  50. {
  51. cout << "func1" << endl;
  52. }
  53.  
  54. void func3(const KeyEvent &)
  55. {
  56. cout << "func3" << endl;
  57. }
  58.  
  59. class func2
  60. {
  61. int data;
  62. public:
  63. explicit func2(int n) : data(n) {}
  64. friend bool operator==(const func2 &lhs,const func2 &rhs)
  65. {
  66. return lhs.data==rhs.data;
  67. }
  68. void operator()(const KeyEvent &)
  69. {
  70. cout << "func2, data=" << data << endl;
  71. }
  72. };
  73.  
  74. struct Caller
  75. {
  76. template<typename F> void operator()(F f)
  77. {
  78. f(1);
  79. }
  80. };
  81.  
  82. class Callbacks
  83. {
  84. vector<KeyCallback> v;
  85. public:
  86. void register_callback(const KeyCallback &callback)
  87. {
  88. v.push_back(callback);
  89. }
  90. void unregister_callback(const KeyCallbackChecker &callback)
  91. {
  92. vector<KeyCallback>::iterator it=find(v.begin(),v.end(),callback);
  93. if(it!=v.end())
  94. v.erase(it);
  95. }
  96. void call_all()
  97. {
  98. for_each(v.begin(),v.end(),Caller());
  99. cout << string(16,'_') << endl;
  100. }
  101. };
  102.  
  103. int main(int argc,char *argv[])
  104. {
  105. Callbacks cb;
  106. cb.register_callback(func1);
  107. cb.register_callback(func2(1));
  108. cb.register_callback(func2(2));
  109. cb.register_callback(func3);
  110. cb.call_all();
  111.  
  112. cb.unregister_callback(func2(2));
  113. cb.call_all();
  114. cb.unregister_callback(func1);
  115. cb.call_all();
  116.  
  117. return 0;
  118. }
  119.  
Success #stdin #stdout 0.01s 2872KB
stdin
Standard input is empty
stdout
func1
func2, data=1
func2, data=2
func3
________________
func1
func2, data=1
func3
________________
func2, data=1
func3
________________