#include #include #include #include using namespace std; template class MultiFuncObject { unordered_map m_funcs; public: MultiFuncObject operator +=(R(*f)()) { m_funcs[typeid(R())] = (void (*)()) f; return *this; } template MultiFuncObject operator +=(R(*f)(A1)) { m_funcs[typeid(R(A1))] = (void (*)()) f; return *this; } template MultiFuncObject operator +=(R(*f)(A1, A2)) { m_funcs[typeid(R(A1, A2))] = (void (*)()) f; return *this; } template MultiFuncObject operator +=(R(*f)(A1, A2, A3)) { m_funcs[typeid(R(A1, A2, A3))] = (void (*)()) f; return *this; } R operator()() const { unordered_map::const_iterator it = m_funcs.find(typeid(R())); if (it != m_funcs.end()) { R(*f)() = (R(*)())(it->second); (*f)(); } } template R operator()(A1 a1) const { unordered_map::const_iterator it = m_funcs.find(typeid(R(A1))); if (it != m_funcs.end()) { R(*f)(A1) = (R(*)(A1))(it->second); (*f)(a1); } } template R operator()(A1 a1, A2 a2) const { unordered_map::const_iterator it = m_funcs.find(typeid(R(A1, A2))); if (it != m_funcs.end()) { R(*f)(A1, A2) = (R(*)(A1, A2))(it->second); (*f)(a1, a2); } } template R operator()(A1 a1, A2 a2, A3 a3) const { unordered_map::const_iterator it = m_funcs.find(typeid(R(A1, A2, A3))); if (it != m_funcs.end()) { R(*f)(A1, A2, A3) = (R(*)(A1, A2, A3))(it->second); (*f)(a1, a2, a3); } } }; struct myData { int myAge = 55; const char* pchar = "myData struct"; enum en_sex { MALE, FEMALE, DIVERS } sex = MALE; }; struct myOtherData : myData { int myOtherAge = 35; }; void _1() { cout << "_1" << endl; } void _2(myData* a) { cout << "_2" << " " << a->pchar << endl; } void _3(myData* a, myOtherData* b) { b->myOtherAge = 25; cout << "_3" << " " << b->myOtherAge << endl; } void _4(myData* a, myOtherData* b, int c) { b->myOtherAge = c; cout << "_3" << " " << b->myOtherAge << endl; } int main() { myData mydata = { 55, "myData struct", myData::MALE }; myOtherData myotherdata; MultiFuncObject funcs; funcs += &_1; funcs += &_2; funcs += &_3; funcs += &_4; funcs(); funcs(&mydata); funcs(&mydata, &myotherdata); funcs(&mydata, &myotherdata, 15); return 0; }