0

I'm writing a wrapper for boost::signals2::signal to get a cleaner, more easy to use interface. Here's what I've come up with:

#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;
};

I'm not sure this is the best wrapper interface I can come up with, and making SomethingHappened a public member might perhaps have some drawbacks. While I don't mind hearing your opinions about that, it is not what this is question is about.

What I'm wondering is how to pass the callback to the += operator. As I've written in ClassThatListensForEvents a callback to a function is no problem, but using the result bind gives a ton of hard-to-read template compiler errors.

Jonatan
  • 3,752
  • 4
  • 36
  • 47
  • Before you begin writing such a wrapper, it's worth reading the [Design Rational](http://www.boost.org/doc/libs/1_53_0/doc/html/signals/s06.html#idp161393904) section. – Igor R. Feb 26 '13 at 12:29
  • I've read that once and I agree with it in the generic context of Boost, but in the context of my application I'm the one to decide and I kinda like that clean interface and the drawbacks are not a big concern to me there. But the `+=` is just sugar, the real reason for writing the wrapper is to hide the `boost::signals2::signal` class from users of the class to reduce complexity and allow other implementations in the future. – Jonatan Feb 26 '13 at 12:54

2 Answers2

3

Your signal has a void() signature, so it takes no parameters. You are trying to assign a boost::bind object that takes one parameter (since it uses _1), which is incompatible. Therefore you get an error. It isn't clear where exactly you're expecting the ev parameter to event_handler to come from. If you bind an actual value instead of _1 the signatures will be compatible.

interjay
  • 107,303
  • 21
  • 270
  • 254
0

Signature of signal and callback differs, I think that's the error

kassak
  • 3,974
  • 1
  • 25
  • 36