Passing pointer to member function to parent in c++ -
how can make following code work? can't make members static, parent doesn't know child , don't have access boost. reason don't use virtual functions child class should able 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 many answers. ones works best me use keywords erasure, std::bind , std::function of course rely on c++11. here full compilable example:
#include <string> #include <map> #include <iostream> #include <functional> using namespace std; class parent { public: void load(string filename) { // see if can find handler based on extension. for(auto = 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 jpeg "<< filename << endl; } void loadpng(string filename) { cout << "loading png "<< filename << endl; } }; int main(int argc, char* argv[]) { child child; child.load("blah.jpg"); child.load("blah.png"); return 0; }
how std::function
, 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)); } ...