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.
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.