Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何按函数名调用函数。一种使用STL::map和类的方法_C++_Code Cleanup - Fatal编程技术网

C++ 如何按函数名调用函数。一种使用STL::map和类的方法

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

基于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<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;
}