#include // Allgemein template class Callback { public: static constexpr auto implFun = ImplFun_; }; template class Callbacks : private Decls... { private: template static Callback findImpl (Callback*); template using BaseDecl = decltype (findImpl (static_cast (nullptr))); public: template static constexpr auto implFun = BaseDecl::implFun; }; // Button-Spezifisch class ButtonObserver { public: inline constexpr ButtonObserver () : next (nullptr) {} friend class Button; virtual bool onClick (int x) = 0; virtual int onDoubleClick (short x, long y) = 0; private: ButtonObserver* next; }; class Button { public: // Dummy marker Types struct OnClick; struct OnDoubleClick; constexpr Button () : firstObserver (nullptr) {} void addObserver (ButtonObserver* obs) { obs->next = firstObserver; firstObserver = obs; } bool onClick (int x) { // Beispiel: Iteriere solange die Observer bis einer "true" zurück gibt for (ButtonObserver* o = firstObserver; o; o = o->next) { if (o->onClick (x)) return true; } return false; } int onDoubleClick (short x, long y) { // Beispiel: Summiere die Rückgabewerte der Observer int sum = 0; for (ButtonObserver* o = firstObserver; o; o = o->next) { sum += o->onDoubleClick (x, y); } return sum; } private: ButtonObserver* firstObserver; }; template class ButtonObserverRelay : public ButtonObserver { public: virtual bool onClick (int x) override { return (static_cast (*this).*(Main::DeclareCallbacks::template implFun)) (x); } virtual int onDoubleClick (short x, long y) override { return (static_cast (*this).*(Main::DeclareCallbacks::template implFun)) (x, y); } }; // Screen-Spezifisch class Screen : public ButtonObserverRelay<0, Screen>, public ButtonObserverRelay<1, Screen> { public: Screen () { btn0.addObserver (static_cast*> (this)); btn1.addObserver (static_cast*> (this)); } bool onButton0Click (int x) { std::cout << "Button 0 Click(" << x << ")" << std::endl; return true; } int onButton0DoubleClick (short x, long y) { std::cout << "Button 0 DoubleClick(" << x << ", " << y << ")" << std::endl; return 0; } bool onButton1Click (int x) { std::cout << "Button 1 Click(" << x << ")" << std::endl; return true; } int onButton1DoubleClick (short x, long y) { std::cout << "Button 1 DoubleClick(" << x << ", " << y << ")" << std::endl; return 0; } Button btn0, btn1; using DeclareCallbacks = Callbacks< Callback, Callback, Callback, Callback >; }; int main () { Screen s; s.btn0.onClick (42); s.btn0.onDoubleClick (12, 3456); s.btn1.onClick (1); s.btn1.onDoubleClick (2, 3); }