#include #include #include // Existierendes API typedef void TPeriodicTimerHandler(void); std::vector g_handlers; void RegisterPeriodicHandler(TPeriodicTimerHandler *pHandler) { g_handlers.push_back(pHandler); } void call_all_handlers() { for(auto f: g_handlers) (*f)(); } // ---------------------------------------------------------------------- // Wrapper mit einem Vorrat an statischen Methoden, die jeweils eins der gespeicherten Callbacks aufrufen. // Fuer Konsistenz und Schreibfaulheit: #define ALL_THE_NUMBERS \ X(0)\ X(1)\ X(2)\ X(3) typedef void (*VoidFuncPtr)(void); class ContextAdapter { public: VoidFuncPtr wrapped_callback(std::function cb_with_context) { the_callbacks.push_back(cb_with_context); const size_t idx_of_last_cb = the_callbacks.size() -1; switch(idx_of_last_cb) { #define X(i) case i: return cb; ALL_THE_NUMBERS #undef X } std::cerr << "no more callbacks\n"; return nullptr; } private: // Quelle: https://stackoverflow.com/a/11583324 template static void cb(void) { the_callbacks[N](); } static std::vector> the_callbacks; }; std::vector> ContextAdapter::the_callbacks; ContextAdapter g_context_adapter; // Das Programm. void dog(void) { std::cerr << "hund\n"; } void cat(void) { std::cerr << "kadse\n"; } class Led { int i; public: Led(int i) : i(i) { RegisterPeriodicHandler( g_context_adapter.wrapped_callback([this](){blink();}) ); } void blink() { std::cerr << "led " << i << " blinkt\n"; } }; int main() { RegisterPeriodicHandler(dog); /// wrap pure void function (unnecessary) RegisterPeriodicHandler( g_context_adapter.wrapped_callback(cat) ); Led led1(1); // Jede Instanz von Led registriert sich selbst. Led led2(2); // wrap lambda with capture; int x = 23; RegisterPeriodicHandler( g_context_adapter.wrapped_callback([&x](){++x;}) ); std::cout << "x=" << x << "\n"; call_all_handlers(); std::cout << "x=" << x << "\n"; }