如何为可以通过名称调用成员函数的c ++类提供函数

时间:2016-12-26 13:49:50

标签: c++ c++11

class f
{
   public:
        run(std::string method,std::string params)
        {
            ...//call foo1 or foo2 with params by "method"
        }

        foo1(std::string a);
        foo2(std::string a);

}

我正在尝试使用map<std::string,std::function<void(std::string)>>来实现它,但是由于非静态成员函数需要指向实例的指针,因此报告了一个错误。我不会像typdef那样使用函数指针f xxx,我预先在funcname和function之间建立一个映射。

3 个答案:

答案 0 :(得分:6)

您的方法是可行的。您只需要std::function定义中的正确原型。

std::map<std::string, std::function<void(f*, std::string)>> func_map;

上述内容当然要求您放在此处的任何会员功能都会返回void并按值接受std::string。没有其他原型可以接受。

您可以像这样存储成员指针:

func_map["foo1"] = &f::foo1;

然后继续在run中调用它们,如此:

func_map[func_name](this, arg);

理想情况下,func_map应为static。所以你要像这样初始化它:

std::map<std::string, std::function<void(f*, std::string)>> f::func_map {
  {"foo1", &f::foo1},
  {"foo2", &f::foo2},
};

如果您想存储的所有内容都是指向成员的指针,那么您也不需要使用std::function。这些可以直接存储。然而,另一方面是您的方法允许可扩展性!

任何接受f指针和std::string按值的自由函数也可以存储在地图中。

答案 1 :(得分:0)

您可以使用此方法解决此问题:

#include <iostream>
#include <string>
#include <map>
#include <functional>

class f{
   public:
        std::map<std::string,std::function<void(f&,std::string)>> func_map{
            {"foo1",[](auto& obj,std::string params){obj.foo1(params);} }, 
               {"foo2",[](auto& obj,std::string params){obj.foo2(params);} }
            }; // make static or accept inputs from outside the class

        void run(std::string method,std::string params){
            func_map.at(method)(*this,params); // treat exceptions as you want
        }   

        void foo1(std::string a){std::cout << "foo1: " << a;}
        void foo2(std::string a){std::cout << "foo2: " << a;}

};

int main(){
    f fff;
    fff.run("foo1","some_params");
    fff.run("foo2","some_params");
}

Online Example

答案 2 :(得分:-3)

C ++中唯一的方法是打开字符串

  if(method.compare"PrintButton")
     classobj.PrintButton(atoi(params.c_str());

字符串是运行时对象,标识符是编译时对象。

然而,你可以去模板路线,以达到同样的目的。