C++ Templates

C++ code posted by Myles Hathcock
created at 20 Sep 15:55

Edit | Back
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>
#include <list>
 
class ScopeCaller
{
  template <class C, void (C::*method)()>
  static void method_thunk(void* obj)
  {
    (static_cast<C*>(obj)->*method)();
  }
 
  template <void (*cb)()>
  static void function_thunk(void*)
  {
    (*cb)();
  }
 
  struct handle
  {
    handle(void* d, void (*cb)(void*)) : data(d), callback(cb) { }
    void operator()(){ callback(data); }
    void* data;
    void (*callback)(void*);
  };
 
  public:
    ~ScopeCaller()
    {
      while(!_cbs.empty())
      {
        (*_cbs.back())();
        delete _cbs.back();
        _cbs.pop_back();
      }
    }
 
    template <class C, void (C::*method)()>
    void Register(C& obj) { _cbs.push_back(new handle((void*)&obj, &method_thunk<C, method>)); }
    template <void (*cb)()>
    void Register() { _cbs.push_back(new handle(NULL, &function_thunk<cb>)); }
 
  private:
    std::list<handle*> _cbs;
};
 
//---------------------------------------------------------------------------
 
void StaticCallback()
{
  std::cout << "Static Callback!" << std::endl;
}
 
class ClassBack
{
  public:
    void Call()
    {
      std::cout << "ClassBack::Call!" << std::endl;
    }
};
 
int main(int, char**)
{
  ScopeCaller exit;
  
  exit.Register<&StaticCallback>();
 
  ClassBack cb;
  exit.Register<ClassBack, &ClassBack::Call>(cb);
 
  return 0;
}
1.31 KB in 6 ms with coderay