I have a project where I have a problem with boost::signals2. To give a short example I've shortened the code to following three classes (All classes are simplified):
class SignalArgs
{
int a_number_;
};
class Plugin
{
protected:
typedef boost::signals2::signal<void (SignalArgs& args)> Event;
public:
typedef Event::slot_type EventHandler;
public:
void addEventHandler(EventHandler& handler)
{
onEvent.connect(handler);
}
private:
Event onEvent;
};
class PluginManager_
{
public:
PluginManager_()
{
p = new Plugin();
// the error occurs in the following line
p->addEventHandler(boost::bind(&PluginManager_::plugin_event_handler, this, _1));
}
private:
Plugin* p;
void plugin_event_handler(SignalArgs& args);
};
While compiling, I always get the error error: no matching function for call to 'Plugin::addEventHandler(boost::_bi::bind_t, boost::_bi::list2, boost::arg<1> > >)'
Okay, the error is simple: The compiler didn't find a function with the same type and number of params. I tried to bypass that with defining an object with the exact type of Plugin::EventHandler
(Which itself is a typedef to boost::signals2::slot1<void, SignalArgs, boost::function<void(SignalArgs)> >&
), but without success.
Did I have overseen something?
boost::bind
returns a temporary (a bind object). In addition, the conversion to slot_type
likely incurs another implicit conversion - resulting in yet another temporary.
Temporaries can only (portably) bind to const-references, which means that you should change the argument to either
void addEventHandler(EventHandler handler);
or
void addEventHandler(EventHandler const& handler);
In C++03 code the latter might eliminate a copy, whereas under C++11 the first one will invoke move-construction since the parameter is an rvalue.