2013-10-20 63 views
0

的方法基于post How to call a function by its name (std::string) in C++?,尝试使用CLASS创建一个版本,但是我的方法不起作用。如何通过名称调用函数。使用STL :: map和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)}’ 

有谁知道什么是错误?

+1

成员函数不是函数。你不能*调用成员函数(比如''myMap [“add”](1,2)'“),因为这没有意义。相反,您需要以某种方式组合* class member *'A :: add'和实例对象'a'。 –

+0

指向成员的指针与指向非成员的指针不同。但是如果你使用了编译器错误,你本可以自己找到它。改变'typedef int(* FnPtr)(int,int);'到'typedef int(A :: * FnPtr)(int,int);'并将其称为'a。*(myMap [“add”])( 42,1337);'。太可怕了,不是吗? – 2013-10-20 17:06:42

+0

这里有一个更基本的问题:成员函数与非成员函数不同。 – juanchopanza

回答

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; 
    // ... 

这样,addsub不是成员函数,这样你就不会得到类型不匹配。至少如图所示,除了调用addsub之外,A的实例没有提供任何功能,所以命名空间在消除问题的同时完成同样的功能。

+2

好看又直接。静态类成员会提供一个类似的替代方案,其优点是可模板化。 –

0

您也可以解决这个问题,由卡尔在评论中提到的,使用std ::函数和std ::绑定(这是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; 
} 
相关问题