1

I have a class with a list of function pointers. These function pointers point to a member function of a sub-class, which was bound like this:

functionList.push_back(std::bind(&SubClass::function, this, std::placeholders::_1,    std::placeholders::_2));

Now, when copying the class with functionList, the function pointers still point to the old class. How can I rebind the function pointer to the new class?

Here an example code:

#include <vector>
#include <functional>

class SomeClass
{

};

class testClass
{
public:
    typedef std::function<void(const SomeClass& var1, const SomeClass& var2)> transitionFunction;




    testClass(){}
    testClass(const testClass&s)
    {
        for(transitionFunction func : s.functionList)
        {
            // how to rebind the function pointer to the new this?
            functionList.push_back("???");
        }
    }

    std::vector<transitionFunction> functionList;


};


class SubClass : public testClass
{
    SubClass()
    {
        functionList.push_back(std::bind(&SubClass::function, this, std::placeholders::_1,    std::placeholders::_2));
    }

    void function(const SomeClass& var1, const SomeClass& var2)
    {

    }

};

Thanks!

veio
  • 507
  • 4
  • 16
  • So you want to call `void SubClass::function(const SomeClass&, const SomeClass&)` on an object of type `testClass` as if the function was declared in `testClass`? That won't work... Maybe you can describe what you are trying to achieve in a more detailed way, so we may find an appropriate solution!? – Simon Kraemer Nov 22 '16 at 11:51
  • It is not possible to "rebind" a function like that. You will have to redesign your classes in order to accomplish your goals in some other way. – Sam Varshavchik Nov 22 '16 at 11:59
  • "Now, when copying the **class** with functionList, the function pointers still point to the old **class**. How can I rebind the function pointer to the new **class**?" You probably mean *object* instead. – eerorika Nov 22 '16 at 12:05
  • Possible duplicate: http://stackoverflow.com/questions/37693605/binding-a-stdfunction-to-the-same-function-of-a-different-object-instance – eerorika Nov 22 '16 at 12:23
  • user2079303, Thanks! That link helps – veio Nov 22 '16 at 19:03

1 Answers1

3

You have to copy your subclass. Actually - you just need default initialization in your copy constructor:

class SubClass : public testClass
{
    ...
    SubClass(const SubClass&) : SubClass()
    {}
    ...
};

In case, your example is very simplified example, then you need to have own function class with rebind function.

[UPDATE]

Remember that rebinding is duty of your subclass - so, I'd do something like this:

Your base class should just have default copy (you might not specify this - default is default):

class testClass
{
public:
    ...
    testClass(const testClass&s) = default;
    ...
};

Next step is to implement rebinding in your subclass:

class SubClass : public testClass
{
public:    
    using transitionFunctionRebindable = 
          std::function<void(SubClass*, const SomeClass&, const SomeClass&)>;

    struct FunctionWrapper
    {
        void operator()(const SomeClass& var1, const SomeClass& var2)
        {
            function(thisObject, var1, var2);
        }

        SubClass* thisObject;
        transitionFunctionRebindable function;
    };

    transitionFunction rebind(transitionFunction& function)
    {
        FunctionWrapper* fr = function.target<FunctionWrapper>();
        if (fr)
        {
            return FunctionWrapper{this, fr->function};
        }
        else
        {
            // in case your base class added something out of your control
            return function;
        }
    }

Construction change a little:

    SubClass()
    {
        functionList.push_back(FunctionWrapper{this, std::bind(&SubClass::function, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)});
    }

Then, copy in your subClass:

    SubClass(const SubClass& source) :  testClass(source)
    {
        for (auto& f: functionList)
            f = rebind(f);
    }

Working demo.

PiotrNycz
  • 23,099
  • 7
  • 66
  • 112
  • Yes, it is simplified. I could do the population of the vector in a virtual function that I call from the base class. Or I get the rebinding to work as in the other thread. Though, not successful yet. – veio Nov 22 '16 at 19:07
  • 1
    I added working demo with explanation how that "rebinding" could be done – PiotrNycz Nov 23 '16 at 09:20