Search code examples
c++ooppolymorphismstd

Using std::function to store methods of inherited classes c++


Is it possible to do something like this?:

// some_header.hpp
#ifndef SOME_HEADER_HPP
#define SOME_HEADER_HPP

class baseclass
{
public:
    baseclass(){};
    std::map<std::string, std::function<void()>> methods_map;
    void call_method(const std::string &name){
        auto it = methods_map.find(name);
        if(it != methods_map.end())
            it->second();
        else std::cout << "Method " << name << " not exists";
    }
};
#endif

And than main.cpp

#include "some_header.hpp"

class inherited : public baseclass{
public:
   inherited():baseclass(){};   
   void new_meth(){
      std::cout << "Hello, stackoverflow!";
   }
};

int main(){
   std::vector<baseclass*> objects;
   auto temp = new inherited();
   objects[0].methods_map["new"]=&temp->new_meth;
   objects[0].call_method("new");
}

This varriant doesn't work, Cannot create a non-constant pointer to member function So, my question: Is it possible to do smth like that and how?


Solution

  • You're close: &temp->new_meth isn't valid, you can capture temp into a void() functor through one of these ways:

    objects[0]->methods_map["new"] = std::bind_front(&inherited::new_meth, temp);
    
    objects[0]->methods_map["new"] = [&] { return temp->new_meth(); }
    

    Notes:

    • objects[0] is an invalid index since you never inserted anything into that vector;
    • objects[0] is a pointer, so you need to dereference it with ->;
    • You should use std::unique_ptr instead of raw owning pointers.