我正在为boost::signals2::signal
编写一个包装器,以获得更简洁,更易于使用的界面。以下是我的想法:
#include <boost/signals2.hpp>
// Wrapper class template for boost::signals2::signal
template<typename T>
class Signal {
typedef typename boost::signals2::signal<T> SignalType;
public:
// Trigger the signal
void operator() () { sig(); }
// Attach a listener
boost::signals2::connection operator+=(const typename SignalType::slot_type& slot)
{ return sig.connect(slot); }
private:
SignalType sig;
};
class ClassThatGeneratesEvents {
public:
void generateEvents(int n) {
while (n-- > 0) {
SomethingHappened();
}
}
Signal<void ()> SomethingHappened;
};
void func()
{
;
}
class ClassThatListensForEvents {
public:
ClassThatListensForEvents(ClassThatGeneratesEvents& ev) {
received_count = 0;
// This works
ev.SomethingHappened += func;
// This doesn't!
ev.SomethingHappened += bind(&ClassThatListensForEvents::event_handler, this, _1);
}
void event_handler() {
received_count++;
}
int received_count;
};
我不确定这是我能提出的最好的包装器界面,并且让SomethingHappened成为公共成员可能会有一些缺点。虽然我不介意听到你的意见,但这不是问题所在。
我想知道的是如何将回调传递给+=
运算符。正如我在ClassThatListensForEvents
中写的那样,对函数的回调没有问题,但使用结果bind
会给出大量难以阅读的模板编译器错误。
答案 0 :(得分:3)
您的信号具有void()
签名,因此不需要参数。您正在尝试分配一个带有一个参数的boost::bind
对象(因为它使用_1
),这是不兼容的。因此,您会收到错误消息。目前尚不清楚您对ev
event_handler
_1
参数的确切位置。如果您绑定实际值而不是{{1}},则签名将是兼容的。
答案 1 :(得分:0)
信号和回调的签名不同,我认为这是错误