Search code examples
c++templatesboostgeneric-programming

Error using boost::bind


Lets say I have an array of functions :

name::Function _actions[10];

The name::Function is just a wrapper for std::function:

class Function{
    public :
        std::function<void(float dt)> Function;

        void exec(float dt){


            Function(dt);
        }
};

And now I have a function to make it generic so it can bind any classes functions :

template<class T>
void bindFunction(int action,void (T::*function)(float) , T* classPtr)
{
    _actions[action] = boost::bind(&function, this, boost::placeholders::_1);
}

And want to use it inside a class that inherits this method (the base class is generic but I think it shouldn´t be a problem)

    DefaultMovableEntity()
    {
        bindFunction(1, &DefaultMovableEntity::func1, this);
    }

    void func1(float dt)
    {
        //Code
    }

However I keep getting erros : enter image description here

What is the main problem? I thought im doing everything right. Thanks.

Edit1 After removing the & from the function and replacing this got following error: enter image description here


Solution

  • There are several problems with your code:

    1. You can't assign your bind result to the array since your array member type is Function, not std::function.

    2. You need to remove & as said before in comments.

    3. Your member named Function is same as class name so compiler may think you are trying to call class constructor.

    The following code should work:

    class Function {
    public:
        std::function<void(float)> func;
    
        void exec(float dt) {
            func(dt);
        }
    };
    

    and bindFunction code:

    template<class T>
    void bindFunction(int action, void (T::*function)(float), T* classPtr)
    {
        _actions[action].func = boost::bind(function, classPtr, boost::placeholders::_1);
    }
    

    However I would suggest slight improvement of Function class so that it doesn't expose its members directly:

    class Function
    {
    private:
        std::function<void(float)> func;
    
    public:
        Function() = default;
        Function(std::function<void(float)> f) : func(f) { }
    
        void exec(float dt) {
            func(dt);
        }
    };
    

    And corresponding change of your bindFunction:

    template<class T>
    void bindFunction(int action, void (T::*function)(float), T* classPtr)
    {
        _actions[action] = Function(boost::bind(function, classPtr, boost::placeholders::_1));
    }