【发布时间】:2013-02-26 12:24:01
【问题描述】:
我正在为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 会产生大量难以阅读的模板编译器错误。
【问题讨论】:
-
在开始编写这样的包装器之前,值得阅读Design Rational 部分。
-
我读过一次,我同意在 Boost 的一般上下文中,但在我的应用程序的上下文中,我是决定者,我有点喜欢那个干净的界面和缺点对我来说不是一个大问题。但是
+=只是糖,编写包装器的真正原因是对类的用户隐藏boost::signals2::signal类,以降低复杂性并允许将来进行其他实现。
标签: c++ boost boost-bind boost-signals boost-signals2