fork download
  1. #include <cstdio>
  2.  
  3. struct GenericObject;
  4. typedef void (GenericObject::*GenericMethod)(GenericObject const&);
  5.  
  6. template<class HandlerBase, class ArgBase>
  7. struct CallTraits
  8. {
  9. typedef void(*CallFunc)(HandlerBase*, GenericMethod, ArgBase const&);
  10.  
  11. template<class TheHandler, class TheArg>
  12. static void callfunc(HandlerBase* h, GenericMethod m, ArgBase const& a)
  13. {
  14. typedef void (TheHandler::*TheMethod)(TheArg const&);
  15.  
  16. TheHandler* th = (TheHandler*)h;
  17. TheMethod tm = (TheMethod)m;
  18. TheArg const& ta = (TheArg const&)a;
  19.  
  20. printf(" < %p->...(*%p)\n", h, &a);
  21. printf(" > %p->...(*%p)\n", th, &ta);
  22. (th->*tm)(ta);
  23. }
  24.  
  25. struct Delegate
  26. {
  27. HandlerBase* h;
  28. GenericMethod m;
  29. CallFunc c;
  30. };
  31.  
  32. template<class TheHandler, class TheArg>
  33. static Delegate make_delegate(TheHandler* th, void (TheHandler::*tm)(TheArg const&))
  34. {
  35. Delegate d = { (HandlerBase*)th, (GenericMethod)tm, &callfunc<TheHandler,TheArg> };
  36. return d;
  37. }
  38.  
  39. static void call_delegate(Delegate const& d, ArgBase const& a)
  40. {
  41. d.c(d.h, d.m, a);
  42. }
  43. };
  44.  
  45. struct A0 { int x; virtual ~A0() {} };
  46. struct A1 { int y; };
  47. struct A : A0, A1 {};
  48.  
  49.  
  50. struct H0 { int x; virtual ~H0() {} };
  51. struct H1 { int y; virtual ~H1() {} };
  52. struct H : H0, H1
  53. {
  54. virtual void foo(A const& a)
  55. {
  56. printf(" = %p->foo(*%p)\n", this, &a);
  57. }
  58. };
  59.  
  60.  
  61.  
  62.  
  63.  
  64. int main()
  65. {
  66. typedef CallTraits<H1, A1> CT;
  67.  
  68. A a; H h;
  69.  
  70. printf("directly:\n");
  71. h.foo(a);
  72.  
  73. printf("delegated:\n");
  74. CT::Delegate d = CT::make_delegate(&h, &H::foo);
  75. printf("delegate: %p %p sizeof(fun)=%d sizeof(method)=%d\n", d.h, d.c, sizeof(d.c), sizeof(d.m));
  76. CT::call_delegate(d, a);
  77. }
  78.  
Success #stdin #stdout 0s 3296KB
stdin
Standard input is empty
stdout
directly:
 = 0xbf9fb780->foo(*0xbf9fb774)
delegated:
delegate: 0xbf9fb788 0x80487a0  sizeof(fun)=4 sizeof(method)=8
 < 0xbf9fb788->...(*0xbf9fb77c)
 > 0xbf9fb780->...(*0xbf9fb774)
 = 0xbf9fb780->foo(*0xbf9fb774)