Passing pointer to member function to parent in c++
c++
Solution
How about `std::function` and `std::bind`:
class Parent
{
public:
void registerFileHandler(string ext, const std::function<void(string)> &f)
{
}
};
class Child : public Parent
{
public:
Child()
{
using namespace std::placeholders; //for _1, _2, _3...
registerFileHandler("jpg", std::bind(&Child::loadJpg, this, _1));
registerFileHandler("png", std::bind(&Child::loadPNG, this, _1));
}
...
Problem
How can I make the following code work? I can't make the members static, Parent doesn't know about Child and I don't have access to boost. The reason I don't use virtual functions is that a Child class should be able to define 1-N handlers. ``` class Parent { public: void registerFileHandler(string ext, memFuncPtr); }; class Child : public Parent { Child() { registerFileHandler("jpg", &Child::loadJpg); registerFileHandler("png", &Child::loadPNG); } void loadJpg(string filename); void loadPNG(string filename); }; ``` EDIT: There were many answers. The ones that works best for me use the keywords erasure, std::bind and std::function which of course rely on c++11. Here is a full compilable example: ``` #include <string> #include <map> #include <iostream> #include <functional> using namespace std; class Parent { public: void load(string filename) { // See if we can find a handler based on the extension. for(auto it = handlers.begin();it!=handlers.end();it++) if(filename.substr(filename.size()-it->first.size(), it->first.size())==it->first) it->second(filename); } template<typename Class> void registerFileHandler(Class* p, void (Class::*func)(string), string ext) { using namespace std::placeholders; //for _1, _2, _3... handlers[ext] = std::bind(func, p, _1); } private: map<string, std::function<void(string)> > handlers; }; class Child : public Parent { public: Child() { registerFileHandler(this, &Child::loadJpg, "jpg"); registerFileHandler(this, &Child::loadPNG, "png"); } void loadJpg(string filename) { cout << "loading the jpeg "<< filename << endl; } void loadPNG(string filename) { cout << "loading the png "<< filename << endl; } }; int main(int argc, char* argv[]) { Child child; child.load("blah.jpg"); child.load("blah.png"); return 0; } ```