继承层次结构中的特定类作为boost :: signals2回调中的类型

时间:2014-10-10 15:01:58

标签: c++ templates inheritance boost-signals2

我在gui-class中使用了boost :: signals2 :: signal,如下所示:

class GuiElement {
    //...
    typedef boost::signals2::signal<void(GuiElement &)> GuiElementSignal;
    virtual GuiElementSignal &getSignal() { return signal_; };
}

所有gui-classes都继承自此类,以便可以注册回调。 Toggle类的示例:

toggle.getSignal().connect([](lx::GuiElement &el) {
    // cast to access toggle specific functions
    state = static_cast<lx::Toggle &>(el).state();
    cout << state << endl;
});

每次我必须将GuiElement转换为SpecificClass以访问特定的类函数时,在回调函数内部。 我想避免这种演员,并将回调签名声明为:toggle.getSignal().connect([](lx::Toggle &el) {...

有没有办法用typedef boost::signals2::signal<void(T &)> GuiElementSignal之类的模板来实现这一点,其中T被类替换?

2 个答案:

答案 0 :(得分:1)

您可以使用curiously recurring template pattern来解决此问题,例如:

template<typename T>
class GuiElement {
    //...
    typedef boost::signals2::signal<void(T&)> GuiElementSignal;
    virtual GuiElementSignal &getSignal() { return signal_; };
};

class Button : public GuiElement<Button> {/* ... */};

答案 1 :(得分:0)

如果您不想公开signal_并且不希望所有gui类都必须使用connect()函数,则可以将所有回调函数注册为{{1} }。例如。 (使用信号2):

slots

注意:如果您想要隐藏#include <iostream> #include <boost/signals2/signal.hpp> #include <boost/bind.hpp> #include <boost/optional/optional_io.hpp> #define registerEvent_(A) registerEvent(boost::bind(A, this, _1, _2)) struct A { typedef boost::signals2::signal<int (int &, int &)> EventSignal; typedef EventSignal::slot_type SlotType; void registerEvent(const SlotType & slot); void triggerAll(int& a1, int& a2); EventSignal signal_; }; void A::registerEvent(const SlotType & slot) { signal_.connect(slot); } void A::triggerAll(int& a1, int& a2) {std::cout << signal_(a1, a2) << "\n";} struct B : public A { B(); int myFunc(int& a1, int& a2); }; B::B() { #ifdef WITHMACRO registerEvent_(&B::myFunc); #else registerEvent(boost::bind(&B::myFunc, this, _1, _2)); #endif } int B::myFunc(int& a1, int& a2) { return a1 + a2 + 1; } int main() { int a1 = 2; int a2 = 3; B b; b.triggerAll(a1, a2); } ,则可以使用宏(WITHMACRO)。