2

How to create a function pointer to any class function knowing only arguments and return type? How to call this function later?

I read about std::function, however I do not have an idea how to implement it without using specific class name like "std::function<void(const ClassName&, int)> f_add_display = &ClassName::func;"

The example below is NOT for compiling, it is only to show the idea I mean:

class collection {
    p* ...; //pointer to any(!) class function with known arguments and return type
} _collection;

class One {
public:
    ...
    bool Foo_1(int, int) {};
    void saveFuncAddr() {_collection.p = this::Foo_1};
};

class Two {
public: 
    bool Foo_2(int, int) {};
    void saveFuncAddr() {_collection.p = this::Foo_2};
};

int main() {
    one* = new One();
    one->saveFuncAddr();
    bool res1 = (*_collection.p)(1, 2);

    two* = new Two();
    two->saveFuncAddr();
    bool res2 = (*_collection.p)(1, 2);
}
DBenson
  • 377
  • 3
  • 12
  • 1
    Use *bind* + *function*: [demo](https://godbolt.org/z/97-QcL) – rafix07 Mar 24 '20 at 21:34
  • Perfect. But didn't work for my case directly, made some changes: void saveFuncAddr() {_collection.p = std::bind(static_cast(&One::Foo_1),this,std::placeholders::_1,std::placeholders::_2); }; – DBenson Mar 24 '20 at 21:58
  • Non-static member functions effectively have a hidden parameter that is a pointer to the class (the `this` pointer). Does your plan include a way to specify which object should be used for the hidden parameter of these functions? – JaMiT Mar 25 '20 at 04:34

1 Answers1

1

First, identifiers beginning with an underscore is reserved in the global namespace, so you shouldn't declare a name like _collection.

You can use lambdas to wrap your member functions:

#include <functional>

struct Collection {
    std::function<bool(int, int)> p; 
} collection;

class One {
public:
    bool Foo_1(int, int) {return true;}
    void saveFuncAddr() 
    {
        collection.p = [this](int a, int b){return this->Foo_1(a, b);};
    }
};

class Two {
public: 
    bool Foo_2(int, int) {return true;}
    void saveFuncAddr() 
    {
        collection.p = [this](int a, int b){return this->Foo_2(a, b);};
    }
};

int main() {
    auto one = new One();
    one->saveFuncAddr();
    bool res1 = (collection.p)(1, 2);
    delete one;

    auto two = new Two();
    two->saveFuncAddr();
    bool res2 = (collection.p)(1, 2);
    delete two;
}
xskxzr
  • 12,442
  • 12
  • 37
  • 77