c++ - How to construct a class with variadic pointer functions as members? -
i want know whether following possible in c++. need construct class store data member std::map
, keys being of type std::string
, , values being function pointers. thing want these function pointers variadic in sense should point functions accepting arbitrary number of arguments, i.e. pointing functions of form
template<class... args> f(args...);
the important bit want able have different arguments different function pointers in map of given instance of class. example, might want create object of class , have map contain 2 pairs, 1 corresponding function having (double, int)
arguments, , having (std::vector, int, int)
arguments. , want able make general, in sense want able add new elements map, possibly different argument lists (although @ compile-time, still need code class without knowing types since want add new elements other files/clients).
what best way implement this?
for saying cant, can, it's not pretty:
this example code output of moc tool, that: stores arbitrary amount of function / method pointers, arbitrary number of arguments.
easiest solution: use qt's moc tool generate you, if cannot or don't want use qt, still can analize code below on how achieve it.
int atcore::qt_metacall(qmetaobject::call _c, int _id, void **_a) { _id = qobject::qt_metacall(_c, _id, _a); if (_id < 0) return _id; if (_c == qmetaobject::invokemetamethod) { if (_id < 25) qt_static_metacall(this, _c, _id, _a); _id -= 25; } else if (_c == qmetaobject::registermethodargumentmetatype) { if (_id < 25) *reinterpret_cast<int*>(_a[0]) = -1; _id -= 25; } return _id; } void atcore::qt_static_metacall(qobject *_o, qmetaobject::call _c, int _id, void **_a) { if (_c == qmetaobject::invokemetamethod) { atcore *_t = static_cast<atcore *>(_o); q_unused(_t) switch (_id) { case 0: _t->printprogresschanged((*reinterpret_cast< const float(*)>(_a[1]))); break; case 1: _t->receivedmessage((*reinterpret_cast< const qbytearray(*)>(_a[1]))); break; case 2: _t->statechanged((*reinterpret_cast< printerstate(*)>(_a[1]))); break; case 3: _t->print((*reinterpret_cast< const qstring(*)>(_a[1]))); break; case 4: _t->stop(); break; case 5: _t->pause((*reinterpret_cast< const qstring(*)>(_a[1]))); break; case 6: _t->resume(); break; case 7: _t->home((*reinterpret_cast< uchar(*)>(_a[1]))); break; case 8: _t->home(); break; case 9: _t->setextrudertemp((*reinterpret_cast< uint(*)>(_a[1])),(*reinterpret_cast< uint(*)>(_a[2]))); break; case 10: _t->setextrudertemp((*reinterpret_cast< uint(*)>(_a[1]))); break; case 11: _t->setextrudertemp(); break; case 12: _t->move((*reinterpret_cast< uchar(*)>(_a[1])),(*reinterpret_cast< uint(*)>(_a[2]))); break; case 13: _t->setbedtemp((*reinterpret_cast< uint(*)>(_a[1]))); break; case 14: _t->setbedtemp(); break; case 15: _t->setfanspeed((*reinterpret_cast< uint(*)>(_a[1])),(*reinterpret_cast< uint(*)>(_a[2]))); break; case 16: _t->setfanspeed((*reinterpret_cast< uint(*)>(_a[1]))); break; case 17: _t->setfanspeed(); break; case 18: _t->setabsoluteposition(); break; case 19: _t->setrelativeposition(); break; case 20: _t->setprinterspeed((*reinterpret_cast< uint(*)>(_a[1]))); break; case 21: _t->setprinterspeed(); break; case 22: _t->setflowrate((*reinterpret_cast< uint(*)>(_a[1]))); break; case 23: _t->setflowrate(); break; case 24: _t->close(); break; default: ; } } else if (_c == qmetaobject::indexofmethod) { int *result = reinterpret_cast<int *>(_a[0]); void **func = reinterpret_cast<void **>(_a[1]); { typedef void (atcore::*_t)(const float & ); if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&atcore::printprogresschanged)) { *result = 0; return; } } { typedef void (atcore::*_t)(const qbytearray & ); if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&atcore::receivedmessage)) { *result = 1; return; } } { typedef void (atcore::*_t)(printerstate ); if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&atcore::statechanged)) { *result = 2; return; } } } }
Comments
Post a Comment