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 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | #include <stdio.h> #include <vector> template<typename R=void, typename A=void, typename F=R (*)(A)> class Method { protected: F method; public : Method(F methodPtr):method(methodPtr){ }; virtual R operator()(A argument) { return this->method(argument); }; typedef F FuncType; }; template<typename A, typename F> class Method<void,A,F> { protected: F method; public : Method(F methodPtr) :method(methodPtr) { }; virtual void operator()(A argument) { this->method(argument); }; typedef F FuncType; }; template<typename R, typename F> class Method<R,void,F> { protected: F method; public : Method(F methodPtr) :method(methodPtr) { }; virtual R operator()() { return this->method(); }; typedef F FuncType; }; template<typename F> class Method<void,void,F> { protected: F method; public : Method(F methodPtr) :method(methodPtr) { }; virtual void operator()() { this->method(); }; typedef F FuncType; }; template<typename C=void, typename R=void, typename A=void, typename F=R (C::*)(A)> class ClassMethod : public Method<R,A,F> { protected: C& owner; public : ClassMethod(C& methodOwner,F methodPtr) :Method<R,A,F>(methodPtr),owner(methodOwner){ }; virtual R operator()(A argument) { return ((this->owner).*(this->method))(argument); }; typedef F FuncType; }; template<typename C, typename A, typename F> class ClassMethod<C,void,A,F>: public Method<void,A,F> { protected: C& owner; public : ClassMethod(C& methodOwner,F methodPtr) :Method<void,A,F>(methodPtr),owner(methodOwner){ }; virtual void operator()(A argument) { ((this->owner).*(this->method))(argument); }; typedef F FuncType; }; template<typename C, typename R, typename F> class ClassMethod<C,R,void,F>: public Method<R,void,F> { protected: C& owner; public : ClassMethod(C& methodOwner,F methodPtr) :Method<R,void,F>(methodPtr),owner(methodOwner){ }; virtual R operator()() { return ((this->owner).*(this->method))(); }; typedef F FuncType; }; template<typename C, typename F> class ClassMethod<C,void,void,F>: public Method<void,void,F> { protected: C& owner; public : ClassMethod(C& methodOwner,F methodPtr) :Method<void,void,F>(methodPtr),owner(methodOwner){ }; virtual void operator()() { ((this->owner).*(this->method))(); }; typedef F FuncType; }; template<typename A> class MethodList { protected: std::vector< Method<void,A> > methods; public: void add(typename Method<void,A>::FuncType fp) { this->methods.push_back(Method<void,A>(fp)); } template<class C> void add(typename C& instance, typename ClassMethod<C,void,A>::FuncType fp) { this->methods.push_back(ClassMethod<C,void,A>(instance,fp)); } void invoke(A argument) { typename std::vector< Method<void,A> >::iterator it; for(it=this->methods.begin() ; it!=this->methods.end() ; it++) { (*it)(argument); } } }; void function1(int arg) { printf("function1(%d)",arg); } class Class1 { public: void function1(int arg) { printf("Class1::function1(%d)",arg); } }; int main(int argc,char* argv[] ) { Class1 inst; MethodList<int> methodList; methodList.add(function1); methodList.add<Class1>(inst,&Class1::function1); methodList.invoke(123); return 0; } |
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDx2ZWN0b3I+Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBSPXZvaWQsIAp0eXBlbmFtZSBBPXZvaWQsCnR5cGVuYW1lIEY9UiAoKikoQSk+IGNsYXNzIE1ldGhvZCB7CQkKcHJvdGVjdGVkOiBGIG1ldGhvZDsKcHVibGljICAgOiBNZXRob2QoRiBtZXRob2RQdHIpOm1ldGhvZChtZXRob2RQdHIpeyB9OwoJCSAgIHZpcnR1YWwgUiBvcGVyYXRvcigpKEEgYXJndW1lbnQpIHsgCgkJCSAgIHJldHVybiB0aGlzLT5tZXRob2QoYXJndW1lbnQpOyAKCQkgICB9OwoJCSAgIHR5cGVkZWYgRiBGdW5jVHlwZTsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIEEsIHR5cGVuYW1lIEY+IGNsYXNzIE1ldGhvZDx2b2lkLEEsRj4gewkJCnByb3RlY3RlZDogRiBtZXRob2Q7CnB1YmxpYyAgIDogTWV0aG9kKEYgbWV0aG9kUHRyKSA6bWV0aG9kKG1ldGhvZFB0cikgeyB9OwoJCSAgIHZpcnR1YWwgdm9pZCBvcGVyYXRvcigpKEEgYXJndW1lbnQpIHsgCgkJCSAgIHRoaXMtPm1ldGhvZChhcmd1bWVudCk7IAoJCSAgIH07CgkJICAgdHlwZWRlZiBGIEZ1bmNUeXBlOwp9OwoKdGVtcGxhdGU8dHlwZW5hbWUgUiwgdHlwZW5hbWUgRj4gY2xhc3MgTWV0aG9kPFIsdm9pZCxGPiB7CQkKcHJvdGVjdGVkOiBGIG1ldGhvZDsKcHVibGljICAgOiBNZXRob2QoRiBtZXRob2RQdHIpIDptZXRob2QobWV0aG9kUHRyKSB7IH07CgkJICAgdmlydHVhbCBSIG9wZXJhdG9yKCkoKSB7IAoJCQkgICByZXR1cm4gdGhpcy0+bWV0aG9kKCk7IAoJCSAgIH07CgkJICAgdHlwZWRlZiBGIEZ1bmNUeXBlOwp9OwoKdGVtcGxhdGU8dHlwZW5hbWUgRj4gY2xhc3MgTWV0aG9kPHZvaWQsdm9pZCxGPiB7CQkKcHJvdGVjdGVkOiBGIG1ldGhvZDsKcHVibGljICAgOiBNZXRob2QoRiBtZXRob2RQdHIpIDptZXRob2QobWV0aG9kUHRyKSB7IH07CgkJICAgdmlydHVhbCB2b2lkIG9wZXJhdG9yKCkoKSB7IAoJCQkgICB0aGlzLT5tZXRob2QoKTsgCgkJICAgfTsKCQkgICB0eXBlZGVmIEYgRnVuY1R5cGU7Cn07Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBDPXZvaWQsCnR5cGVuYW1lIFI9dm9pZCwgCnR5cGVuYW1lIEE9dm9pZCwKdHlwZW5hbWUgRj1SIChDOjoqKShBKT4gCmNsYXNzIENsYXNzTWV0aG9kIDogcHVibGljIE1ldGhvZDxSLEEsRj4gewkJCnByb3RlY3RlZDogQyYgb3duZXI7CnB1YmxpYyAgIDogQ2xhc3NNZXRob2QoQyYgbWV0aG9kT3duZXIsRiBtZXRob2RQdHIpIAoJCQkgICA6TWV0aG9kPFIsQSxGPihtZXRob2RQdHIpLG93bmVyKG1ldGhvZE93bmVyKXsgfTsKCQkgICB2aXJ0dWFsIFIgb3BlcmF0b3IoKShBIGFyZ3VtZW50KSB7IAoJCQkgICByZXR1cm4gKCh0aGlzLT5vd25lcikuKih0aGlzLT5tZXRob2QpKShhcmd1bWVudCk7IAoJCSAgIH07CgkJICAgdHlwZWRlZiBGIEZ1bmNUeXBlOwp9OwoKdGVtcGxhdGU8dHlwZW5hbWUgQywgdHlwZW5hbWUgQSwgdHlwZW5hbWUgRj4gCmNsYXNzIENsYXNzTWV0aG9kPEMsdm9pZCxBLEY+OiBwdWJsaWMgTWV0aG9kPHZvaWQsQSxGPiB7CnByb3RlY3RlZDogQyYgb3duZXI7CnB1YmxpYyAgIDogQ2xhc3NNZXRob2QoQyYgbWV0aG9kT3duZXIsRiBtZXRob2RQdHIpIAoJCQkgICA6TWV0aG9kPHZvaWQsQSxGPihtZXRob2RQdHIpLG93bmVyKG1ldGhvZE93bmVyKXsgfTsKCQkgICB2aXJ0dWFsIHZvaWQgb3BlcmF0b3IoKShBIGFyZ3VtZW50KSB7IAoJCQkgICAoKHRoaXMtPm93bmVyKS4qKHRoaXMtPm1ldGhvZCkpKGFyZ3VtZW50KTsgCgkJICAgfTsKCQkgICB0eXBlZGVmIEYgRnVuY1R5cGU7Cn07Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBDLCB0eXBlbmFtZSBSLCB0eXBlbmFtZSBGPiAKY2xhc3MgQ2xhc3NNZXRob2Q8QyxSLHZvaWQsRj46IHB1YmxpYyBNZXRob2Q8Uix2b2lkLEY+IHsKcHJvdGVjdGVkOiBDJiBvd25lcjsKcHVibGljICAgOiBDbGFzc01ldGhvZChDJiBtZXRob2RPd25lcixGIG1ldGhvZFB0cikgCgkJCSAgIDpNZXRob2Q8Uix2b2lkLEY+KG1ldGhvZFB0ciksb3duZXIobWV0aG9kT3duZXIpeyB9OwoJCSAgIHZpcnR1YWwgUiBvcGVyYXRvcigpKCkgeyAKCQkJICAgcmV0dXJuICgodGhpcy0+b3duZXIpLioodGhpcy0+bWV0aG9kKSkoKTsgCgkJICAgfTsKCQkgICB0eXBlZGVmIEYgRnVuY1R5cGU7Cn07Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBDLCB0eXBlbmFtZSBGPiAKY2xhc3MgQ2xhc3NNZXRob2Q8Qyx2b2lkLHZvaWQsRj46IHB1YmxpYyBNZXRob2Q8dm9pZCx2b2lkLEY+IHsKcHJvdGVjdGVkOiBDJiBvd25lcjsKcHVibGljICAgOiBDbGFzc01ldGhvZChDJiBtZXRob2RPd25lcixGIG1ldGhvZFB0cikgCgkJCSAgIDpNZXRob2Q8dm9pZCx2b2lkLEY+KG1ldGhvZFB0ciksb3duZXIobWV0aG9kT3duZXIpeyB9OwoJCSAgIHZpcnR1YWwgdm9pZCBvcGVyYXRvcigpKCkgeyAKCQkJICAgKCh0aGlzLT5vd25lcikuKih0aGlzLT5tZXRob2QpKSgpOyAKCQkgICB9OwoJCSAgIHR5cGVkZWYgRiBGdW5jVHlwZTsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIEE+IGNsYXNzIE1ldGhvZExpc3Qgewpwcm90ZWN0ZWQ6CglzdGQ6OnZlY3RvcjwgTWV0aG9kPHZvaWQsQT4gPiBtZXRob2RzOwpwdWJsaWM6CQoJdm9pZCBhZGQodHlwZW5hbWUgTWV0aG9kPHZvaWQsQT46OkZ1bmNUeXBlIGZwKSB7CgkJdGhpcy0+bWV0aG9kcy5wdXNoX2JhY2soTWV0aG9kPHZvaWQsQT4oZnApKTsKCX0KCXRlbXBsYXRlPGNsYXNzIEM+IHZvaWQgYWRkKHR5cGVuYW1lIEMmIGluc3RhbmNlLAoJCXR5cGVuYW1lIENsYXNzTWV0aG9kPEMsdm9pZCxBPjo6RnVuY1R5cGUgZnApIHsKCQkJdGhpcy0+bWV0aG9kcy5wdXNoX2JhY2soQ2xhc3NNZXRob2Q8Qyx2b2lkLEE+KGluc3RhbmNlLGZwKSk7CgkJfQoJCXZvaWQgaW52b2tlKEEgYXJndW1lbnQpIHsKCQkJdHlwZW5hbWUgc3RkOjp2ZWN0b3I8IE1ldGhvZDx2b2lkLEE+ID46Oml0ZXJhdG9yIGl0OwoJCQlmb3IoaXQ9dGhpcy0+bWV0aG9kcy5iZWdpbigpIDsgaXQhPXRoaXMtPm1ldGhvZHMuZW5kKCkgOyBpdCsrKSB7CgkJCQkoKml0KShhcmd1bWVudCk7CgkJCX0KCQl9Cn07CgoKdm9pZCBmdW5jdGlvbjEoaW50IGFyZykgewoJcHJpbnRmKCJmdW5jdGlvbjEoJWQpIixhcmcpOwp9CgpjbGFzcyBDbGFzczEgewpwdWJsaWM6Cgl2b2lkIGZ1bmN0aW9uMShpbnQgYXJnKSB7CgkJcHJpbnRmKCJDbGFzczE6OmZ1bmN0aW9uMSglZCkiLGFyZyk7Cgl9Cn07CgppbnQgbWFpbihpbnQgYXJnYyxjaGFyKiBhcmd2W10gKSAgICAgICAgICAgICAgICAgICAgICAgIAp7ICAgICAgCglDbGFzczEgaW5zdDsKCU1ldGhvZExpc3Q8aW50PiBtZXRob2RMaXN0OwoKCW1ldGhvZExpc3QuYWRkKGZ1bmN0aW9uMSk7CgltZXRob2RMaXN0LmFkZDxDbGFzczE+KGluc3QsJkNsYXNzMTo6ZnVuY3Rpb24xKTsKCW1ldGhvZExpc3QuaW52b2tlKDEyMyk7CgoJcmV0dXJuIDA7Cn0gICA=
prog.cpp:96: error: expected nested-name-specifier before ‘C’
prog.cpp:96: error: expected `(' before ‘C’
prog.cpp:97: error: expected `(' before ‘fp’
prog.cpp:97: error: variable or field ‘add’ declared void
prog.cpp: In function ‘int main(int, char**)’:
prog.cpp:126: error: expected primary-expression before ‘>’ token
prog.cpp:126: warning: left-hand operand of comma has no effect
-
result: Compilation error (maybe you wish to see an example for C++ 4.7.2)


