0

我在这样的 gui 类中使用 boost::signals2::signal :

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

所有 gui 类都继承自此类,以便可以注册回调。一个Toggle类的例子:

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

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

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

4

2 回答 2

1

你可以使用奇怪重复的模板模式来解决这个问题,例如:

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

class Button : public GuiElement<Button> {/* ... */};
于 2015-04-28T16:25:06.430 回答
0

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

#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如果您甚至想隐藏bind.

于 2017-09-15T14:37:23.540 回答