0

基于帖子How to call a function by its name (std::string) in C++? ,尝试使用 CLASS 制作版本,但我的方法不起作用。

class A {
    public:
        int add(int i, int j) { return i+j; }
        int sub(int i, int j) { return i-j; }
};

typedef int (*FnPtr)(int, int);

int main(int argc, char* argv[]) {

// initialization:
std::map<std::string, FnPtr> myMap;
A a;
myMap["add"] = a.add;
myMap["sub"] = a.sub;

返回此错误:

main.cpp:31:22: error: cannot convert ‘A::add’ from type ‘int (A::)(int, int)’ to type ‘std::map<std::basic_string<char>, int (*)(int, int)>::mapped_type {aka int (*)(int, int)}’
main.cpp:32:22: error: cannot convert ‘A::sub’ from type ‘int (A::)(int, int)’ to type ‘std::map<std::basic_string<char>, int (*)(int, int)>::mapped_type {aka int (*)(int, int)}’

有谁知道错误是什么?

4

2 回答 2

2

至少正如你所展示的那样,你class A提供的只是问题。如果你把它变成一个命名空间,事情会容易得多。

namespace A {
    int add(int i, int j) { return i+j; }
    int sub(int i, int j) { return i-j; }
};

typedef int (*FnPtr)(int, int);

int main(int argc, char* argv[]) {
    std::map<std::string, FnPtr> myMap;
    myMap["add"] = A::add;
    myMap["sub"] = A::sub;
    // ...

这样,add并且sub不是成员函数,因此您不会得到类型不匹配。至少如图所示,A除了调用addand之外, 的实例没有提供任何功能sub,因此命名空间在消除问题的同时完成了同样多的工作。

于 2013-10-20T17:11:47.053 回答
0

正如 Kal 在评论中提到的那样,您还可以使用 std::function 和 std::bind 解决问题(这是 C++11 所以):

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

class A {
    public:
        int add(int i, int j) { return i+j; }
        int sub(int i, int j) { return i-j; }
};


int main(int argc, char* argv[])
{
  std::map<std::string, std::function<int(int,int)>> myMap;
  A a;
  myMap["add"] = std::bind(&A::add,&a,std::placeholders::_1,std::placeholders::_2);
  myMap["sub"] = std::bind(&A::sub,&a,std::placeholders::_1,std::placeholders::_2);

  std::cout<<myMap["sub"](7,2)<<std::endl;
}
于 2013-10-20T17:34:33.760 回答