how to connect a member function to a boost signal

518 Views Asked by At

Is there a way to avoid the use of boost::bind to attach a member function to a boost::signal slot?

The only way I can get it to work is to use bind like this:

mysignal.connect(boost::bind(&myClass::listenerMember, this, _1, _2));

but I really want it to look more like this:

mysignal.connect(myClass::listenerMember);

Here is some sample code to show it a bit better:

#include <iostream>
#include <cstdlib>
#include "boost/signals2.hpp"

class window
{
    public:
    boost::signals2::signal<void(int,int)>  sigLButtonDown;

    void simulateCallback(){ sigLButtonDown(1,3);}
};

class windowListener
{
    public:
    windowListener(window * pwindow) { pwindow->sigLButtonDown.connect(boost::bind(&windowListener::listenerMember, this, _1, _2));}


    void listenerMember(int x, int y) {    std::cout << "ping!" << std::endl;}

};

int main()
{
    window w;
    windowListener l(&w);

    std::cout << "Here goes!" << std::endl;    
    w.simulateCallback();

}
1

There are 1 best solutions below

1
0x4d696e68 On

maybe too late, but this is my solution

#define SIGNAL_TEMPLATE_BASE boost::signals2::signal<void(Args...)>
template<typename... Args>
class signal_t : public SIGNAL_TEMPLATE_BASE
{
public:
    template<typename T>
    inline boost::signals2::connection connect(T* obj,void(T::* func)(Args...)) {
        return SIGNAL_TEMPLATE_BASE::connect([obj,func](Args... args) {
            (obj->*func)(boost::forward<Args>(args)...);
        });
    }
    inline boost::signals2::connection connect(const boost::function<void(Args...)>& func) {
        return SIGNAL_TEMPLATE_BASE::connect(func);
    }
    template<typename T>
    inline boost::signals2::connection connect(const int &group, T* obj,void(T::*func)(Args...)) {
        return SIGNAL_TEMPLATE_BASE::connect(group,[obj,func](Args... args) {
            (obj->*func)(boost::forward<Args>(args)...);
        });
    }
    inline boost::signals2::connection connect(const int& group,const boost::function<void(Args...)>& func) {
        return SIGNAL_TEMPLATE_BASE::connect(group,func);
    }
};

example

class Button {
public:
    signal_t<int> Click;

    void Action() {
        Click(42);
    }
};

class Window {
public:
    Button btnA;

    void OnClickA(int val) {
        std::cout << val << std::endl;
    }

    Window() {
        btnA.Click.connect(this,&Window::OnClickA);
    }
};