C++ 如何按函数名调用函数。一种使用STL::map和类的方法
基于post,我尝试使用类制作一个版本,但我的方法不起作用C++ 如何按函数名调用函数。一种使用STL::map和类的方法,c++,code-cleanup,C++,Code Cleanup,基于post,我尝试使用类制作一个版本,但我的方法不起作用 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<st
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;
A类{
公众:
intadd(inti,intj){返回i+j;}
intsub(inti,intj){返回i-j;}
};
类型定义内部(*FnPtr)(内部,内部);
int main(int argc,char*argv[]){
//初始化:
std::map myMap;
A A;
myMap[“添加”]=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)}’
main.cpp:31:22:错误:无法将“A::add”从类型“int(A::)(int,int)”转换为类型“std::map::mapped_type{aka int(*)(int,int)}”
main.cpp:32:22:错误:无法将“A::sub”从类型“int(A::)(int,int)”转换为类型“std::map::mapped_type{aka int(*)(int,int)}”
有人知道错误是什么吗?至少正如您所展示的,您的
类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;
// ...
名称空间A{
intadd(inti,intj){返回i+j;}
intsub(inti,intj){返回i-j;}
};
类型定义内部(*FnPtr)(内部,内部);
int main(int argc,char*argv[]){
std::map myMap;
myMap[“add”]=A::add;
myMap[“sub”]=A::sub;
// ...
通过这种方式,
add
和sub
不是成员函数,因此不会出现类型不匹配的情况。至少如图所示,A
的实例除了调用add
和sub
之外,没有提供任何功能,因此命名空间在消除问题的同时也能发挥同样的作用。您还可以解决正如Kal在评论中提到的,使用std::function和std::bind(这是C++11 so)解决问题:
#包括
#包括
#包括
#包括
甲级{
公众:
intadd(inti,intj){返回i+j;}
intsub(inti,intj){返回i-j;}
};
int main(int argc,char*argv[])
{
std::map myMap;
A A;
myMap[“add”]=std::bind(&A::add,&A,std::占位符::_1,std::占位符::_2);
myMap[“sub”]=std::bind(&A::sub,&A,std::占位符::_1,std::占位符::_2);
std::coutMember函数不是函数。不能调用成员函数(如“myMap[“add”](1,2)
”),因为这没有任何意义。相反,您需要以某种方式将类成员A::add
和实例对象A
组合在一起。指向成员的指针与指向非成员的指针不同。但是,如果您用谷歌搜索编译器错误,您将能够自己找到它。更改typedef int(*FnPtr)(int,int);
到typedefint(A::*FnPtr)(int,int);
并像A.*(myMap[“add”])(421337)那样调用它
。太可怕了,不是吗?这里有一个更基本的问题:成员函数与非成员函数不同。可能使用std::function
+std::bind
是类a
的所有函数的成员吗?简单明了。静态类成员将提供类似的选择,其好处是是可模板化的。
#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;
}