0

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?

Felix
  • 2,531
  • 14
  • 25
  • 1
    @PiotrS. Care to post an answer, even if you think it's not worth it? Posting answer material in the comments misrepresents the Question as if it is unanswered, while it prevents others from answering because ... well, they'd be "stealing" your comment... – sehe Sep 03 '14 at 12:53
  • @PiotrS. There's no diff with `std::{bind,placeholders::_1}` for me. Perhaps you're using MSVC and benefitting from it's extension that allows a temporary to bind to a non-const reference? – sehe Sep 03 '14 at 13:38

1 Answers1

2

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.


sehe
  • 374,641
  • 47
  • 450
  • 633