我在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被类替换?
答案 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
)。