如何传递信号回调(使用boost :: bind)

时间:2013-02-26 12:24:02

标签: c++ boost boost-bind boost-signals boost-signals2

我正在为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会给出大量难以阅读的模板编译器错误。

2 个答案:

答案 0 :(得分:3)

您的信号具有void()签名,因此不需要参数。您正在尝试分配一个带有一个参数的boost::bind对象(因为它使用_1),这是不兼容的。因此,您会收到错误消息。目前尚不清楚您对ev event_handler _1参数的确切位置。如果您绑定实际值而不是{{1}},则签名将是兼容的。

答案 1 :(得分:0)

信号和回调的签名不同,我认为这是错误