#ifndef DUMMYCLASS_H #define DUMMYCLASS_H namespace delegate { class DummyClass{}; } #endif
#ifndef METHODSTORAGE_H #define METHODSTORAGE_H #include "DummyClass.h" namespace delegate { class MethodStorage { public: typedef DummyClass GenericClass; typedef void (GenericClass::*GenericMemberFunctionPtr)(); typedef void (*GenericFunctionPtr)(); MethodStorage() :m_obj(0), m_member_fnptr(0), m_fnptr(0) { } inline bool operator == (MethodStorage const& other) const{return this->equals(other);} inline bool operator != (MethodStorage const& other) const{return !this->equals(other);} inline bool equals(MethodStorage const& other) const { return m_obj == other.m_obj && m_member_fnptr == other.m_member_fnptr && m_fnptr == other.m_fnptr; } //protected: GenericClass *m_obj; GenericMemberFunctionPtr m_member_fnptr; GenericFunctionPtr m_fnptr; }; }; #endif
#ifndef METHODWRAPPER_H #define METHODWRAPPER_H #include "MethodStorage.h" namespace delegate { ///This "Signature" is not a complete function pointer ///corresponding signature to void (*)(int) is void(int) ///and void (SomeClassType::*)(int) is void(int) as well template<typename Signature> class MethodWrapper; template<> class MethodWrapper< void () > { public: template<typename ClassType,typename MemberFunctionClass> MethodWrapper(ClassType const& obj,void (MemberFunctionClass::*ptr)(void) const) { m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj); m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr); internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)() >; } template<typename ClassType,typename MemberFunctionClass> MethodWrapper(ClassType & obj,void (MemberFunctionClass::*ptr)(void)const ) { m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj); m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr); internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)() >; } template<typename ClassType,typename MemberFunctionClass> MethodWrapper(ClassType & obj,void (MemberFunctionClass::*ptr)(void)) { m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj); m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr); internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)() >; } MethodWrapper(void (*ptr)(void)) { m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(this); m_method.m_fnptr = reinterpret_cast<MethodStorage::GenericFunctionPtr>(ptr); internal_call = &MethodWrapper::executeFunction< MethodWrapper , void (*)() >; } void operator()() { (this->*internal_call)(m_method.m_obj); } private: typedef void (MethodWrapper::*internal_call_type)(void*); MethodStorage m_method; internal_call_type internal_call; template<typename ClassType,typename FunctionPtrType> void executeMemberFunction(void* obj) { (reinterpret_cast<ClassType*>(obj)->*reinterpret_cast<FunctionPtrType>(m_method.m_member_fnptr))(); } template<typename ClassType,typename FunctionPtrType> void executeFunction(void* obj) { (*reinterpret_cast<FunctionPtrType>(m_method.m_fnptr))(); } }; template<typename ReturnType> class MethodWrapper< ReturnType () > { public: template<typename ClassType,typename MemberFunctionClass> MethodWrapper(ClassType const& obj,ReturnType (MemberFunctionClass::*ptr)(void) const) { m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj); m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr); internal_call = &MethodWrapper::executeMemberFunction< ClassType , ReturnType (MemberFunctionClass::*)() >; } template<typename ClassType,typename MemberFunctionClass> MethodWrapper(ClassType & obj,ReturnType (MemberFunctionClass::*ptr)(void)const ) { m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj); m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr); internal_call = &MethodWrapper::executeMemberFunction< ClassType , ReturnType (MemberFunctionClass::*)() >; } template<typename ClassType,typename MemberFunctionClass> MethodWrapper(ClassType & obj,ReturnType (MemberFunctionClass::*ptr)(void)) { m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj); m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr); internal_call = &MethodWrapper::executeMemberFunction< ClassType , ReturnType (MemberFunctionClass::*)() >; } MethodWrapper(ReturnType (*ptr)(void)) { m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(this); m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr); internal_call = &MethodWrapper::executeFunction< MethodWrapper , ReturnType (*)() >; } ReturnType operator()() { return (this->*internal_call)(m_method.m_obj); } private: typedef void (MethodWrapper::*internal_call_type)(void); MethodStorage m_method; internal_call_type internal_call; template<typename ClassType,typename FunctionPtrType> ReturnType executeMemberFunction(void* obj) { return (reinterpret_cast<ClassType*>(obj)->*reinterpret_cast<FunctionPtrType>(m_method.m_member_fnptr))(); } template<typename ClassType,typename FunctionPtrType> ReturnType executeFunction(void* obj) { return (*reinterpret_cast<FunctionPtrType>(m_method.m_fnptr))(); } }; template<typename ArgType0> class MethodWrapper< void ( ArgType0 ) > { public: template<typename ClassType,typename MemberFunctionClass> MethodWrapper(ClassType const& obj,void (MemberFunctionClass::*ptr)(ArgType0) const) { m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(const_cast<ClassType*>(&obj)); m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr); internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)(ArgType0) >; } template<typename ClassType,typename MemberFunctionClass> MethodWrapper(ClassType & obj,void (MemberFunctionClass::*ptr)(ArgType0)const ) { m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj); m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr); internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)(ArgType0) >; } template<typename ClassType,typename MemberFunctionClass> MethodWrapper(ClassType const& obj,void (MemberFunctionClass::*ptr)(ArgType0)) { m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(const_cast<ClassType*>(&obj)); m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr); internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)(ArgType0) >; } template<typename ClassType,typename MemberFunctionClass> MethodWrapper(ClassType & obj,void (MemberFunctionClass::*ptr)(ArgType0)) { m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj); m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr); internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)(ArgType0) >; } MethodWrapper(void (*ptr)(ArgType0)) { m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(this); m_method.m_fnptr = reinterpret_cast<MethodStorage::GenericFunctionPtr>(ptr); internal_call = &MethodWrapper::executeFunction< MethodWrapper , void (*)(ArgType0) >; } void operator()(ArgType0 arg0) { (this->*internal_call)(m_method.m_obj, arg0); } private: typedef void (MethodWrapper::*internal_call_type)(void*,ArgType0); MethodStorage m_method; internal_call_type internal_call; template<typename ClassType,typename FunctionPtrType> void executeMemberFunction(void* obj,ArgType0 arg0) { (reinterpret_cast<ClassType*>(obj)->*reinterpret_cast<FunctionPtrType>(m_method.m_member_fnptr))(arg0); } template<typename ClassType,typename FunctionPtrType> void executeFunction(void* obj,ArgType0 arg0) { (*reinterpret_cast<FunctionPtrType>(m_method.m_fnptr))(arg0); } }; template<typename ReturnType,typename ArgType0> class MethodWrapper< ReturnType ( ArgType0 ) > { public: template<typename ClassType,typename MemberFunctionClass> MethodWrapper(ClassType const& obj,ReturnType (MemberFunctionClass::*ptr)(ArgType0) const) { m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj); m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr); internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)(ArgType0) >; } template<typename ClassType,typename MemberFunctionClass> MethodWrapper(ClassType & obj,ReturnType (MemberFunctionClass::*ptr)(ArgType0)const ) { m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj); m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr); internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)(ArgType0) >; } template<typename ClassType,typename MemberFunctionClass> MethodWrapper(ClassType & obj,ReturnType (MemberFunctionClass::*ptr)(ArgType0)) { m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj); m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr); internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)(ArgType0) >; } MethodWrapper(ReturnType (*ptr)(ArgType0)) { m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(this); m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr); internal_call = &MethodWrapper::executeFunction< MethodWrapper , void (*)(ArgType0) >; } ReturnType operator()(ArgType0 arg0) { return (this->*internal_call)(m_method.m_obj,arg0); } private: typedef ReturnType (MethodWrapper::*internal_call_type)(void*,ArgType0); MethodStorage m_method; internal_call_type internal_call; template<typename ClassType,typename FunctionPtrType> ReturnType executeMemberFunction(void* obj,ArgType0 arg0) { return (reinterpret_cast<ClassType*>(obj)->*reinterpret_cast<FunctionPtrType>(m_method.m_member_fnptr))(arg0); } template<typename ClassType,typename FunctionPtrType> ReturnType executeFunction(void* obj,ArgType0 arg0) { return (*reinterpret_cast<FunctionPtrType>(m_method.m_fnptr))(arg0); } }; } #endif
compiler:MinGW 4.5.2 / VC++2010
C#式的delegate的重点之一是省略掉类型信息.
class delegate { public: delegate() : object_ptr(0) , stub_ptr(0) {} template <class T, void (T::*TMethod)(int)> static delegate from_method(T* object_ptr) { delegate d; d.object_ptr = object_ptr; d.stub_ptr = &method_stub<T, TMethod>; // #1 return d; } void operator()(int a1) const { return (*stub_ptr)(object_ptr, a1); } private: typedef void (*stub_type)(void* object_ptr, int); void* object_ptr; stub_type stub_ptr; template <class T, void (T::*TMethod)(int)> static void method_stub(void* object_ptr, int a1) { T* p = static_cast<T*>(object_ptr); return (p->*TMethod)(a1); // #2 } };
非常巧妙地隐藏掉了类型信息。但是本人对虚继承的委托还没有好的解决方法,也理解不了虚继承的成员函数的hack:http://www.codeproject.com/KB/cpp/FastDelegate.aspx