Search code examples
classboostfunctor

Compile Errors in Class with User Defined Functions


I am trying to build a class that stores a user-defined function inside of it for later use. I have decided to use the boost::function object to do so.

However, I get the following error on compile:

error: no match for ‘operator=’ in ‘((SomeClass*)this)->SomeClass::someFunction = ((SomeClass*)this)->SomeClass::DefaultFunction’

I do not understand this error, since someFunction and DefaultFunction should, as far as I can see, have the same types.

The code is shown below:

#include <boost/function.hpp>

class SomeClass{
    private:
            boost::function<int(int)> someFunction;
            int DefaultFunction(int i);

    public:
            SomeClass();
            ~SomeClass();
            void SetFunction(int (*f)(int));
    };

int SomeClass::DefaultFunction(int i){
    return i+1;

}

SomeClass::SomeClass(){
    someFunction=DefaultFunction;
}

~SomeClass::SomeClass(){

 }

 void SomeClass::SetFunction(int (*f)(int i)){
        someFunction=f;
 }

 void MyProgram(){
        SomeClass s;
 }

Can anyone offer any pointers as to how to construct such an object? Alternatively, iff there is a better way than the one I am attempting, could you explain it to me?

Kindest regards!


Solution

  • DefaultFunction is a member function of SomeClass. Member function is called for some instance of SomeClass. This function takes "hidden" pointer to SomeClass instance as its first parameter addition to int. So member function is not the same as free function.

    Your someFunction is object of boost::function, so it is wrapper for callable object. Your requirements to that object are: take int and returns int. In order to assign DefaultFunction (as member function) to someFunction you need to create this callable object. Here you need to specify for which instance of SomeClass this object will be called, to do that use boost::bind:

    SomeClass::SomeClass(){
        someFunction=boost::bind(&SomeClass::DefaultFunction, this, boost::placeholders::_1);
    }
    

    In the code above you create callable object which will behave as

    struct unnamedClass {
        SomeClass* sc;
        unnamedClass (SomeClass* sc) : sc(sc) {} // here sc is this of SomeClass
    
        int operator()(int arg)
        {
            return sc->DefaultFunction(arg);
        }
    };
    

    so when you invoke someFunction(10) it takes 10 as argument and call DefaultFunction for current this instance.

    This

    void SomeClass::SetFunction(int (*f)(int i)){
        someFunction=f;
     }
    

    works because f is free function, which takes no hidden - pointer to class instance.