std::function指针错误: 无法将&A::a转换为类型std::function<>&&。

3

我正在尝试将字符串映射到函数指针,以便可以使用 iter->second(arg) 调用函数而不是 if-else。 我编写了一个简单的版本,没有使用 class,它按预期工作。 但当我按下面的方式修改时,它会显示编译错误。

 #include <functional>
 #include <iostream>
 #include <unordered_map>
 #include <string>

 using std::string;

 class A{
     private:
     int a(int num, string s) { return s.size() + num; }
     int b(int num, string s) { return num - s.size(); }

     public:
     void ido(string str){
         typedef std::function<int(int, string)> process_func;
         std::unordered_map<string, process_func> m;
         m.insert(std::make_pair<string, process_func>("a", &A::a));
         // using std::placeholders::_1;
         // m.insert(std::make_pair<string, process_func>("a", std::bind(&A::a, this, _1)));
         // m["a"] = std::bind(&A::a, this, _1);
         // m.insert({{"a", &A::a}, {"b", &A::b}});

         auto x = m.find(str);
         if(x == m.end()) {
             std::cout << "Not supported!" << std::endl;
         }
         std::cout << x->second(10, "hello") << std::endl;
     }
 };
 int main(int argc, char* argv[]) {
     A a;
     a.ido(string(argv[1]));
     return 0;
 }

错误信息如下:
function.cc: In member function ‘void A::ido(std::string)’:
function.cc:17:65: error: no matching function for call to ‘make_pair(const char [2], int (A::*)(int, std::string))’
         m.insert(std::make_pair<string, process_func>("a", &A::a));
                                                                 ^
function.cc:17:65: note: candidate is:
In file included from /usr/include/c++/4.8.2/utility:70:0,
                 from /usr/include/c++/4.8.2/tuple:38,
                 from /usr/include/c++/4.8.2/functional:55,
                 from function.cc:1:
/usr/include/c++/4.8.2/bits/stl_pair.h:276:5: note: template<class _T1, class _T2> constexpr std::pair<typename std::__decay_and_strip<_Tp>::__type, typename std::__decay_and_strip<_T2>::__type> std::make_pair(_T1&&, _T2&&)
     make_pair(_T1&& __x, _T2&& __y)
     ^
/usr/include/c++/4.8.2/bits/stl_pair.h:276:5: note:   template argument deduction/substitution failed:
function.cc:17:65: note:   cannot convert ‘&A::a’ (type ‘int (A::*)(int, std::string) {aka int (A::*)(int, std::basic_string<char>)}’) to type ‘std::function<int(int, std::basic_string<char>)>&&’
         m.insert(std::make_pair<string, process_func>("a", &A::a));

这个错误是什么意思?如何修复它?


1
看起来像是这个的重复:https://dev59.com/wWsz5IYBdhLWcg3w6MJS - Eljay
1个回答

2

虽然你的函数'a'和'b'不依赖于'this'(它们不访问类A内部的任何内容),但编译器并不足够聪明以推断这一点。因此,错误意味着你正在尝试将“指向方法”的指针转换为“指向函数”的指针,这是不正确的转换。“指向方法”需要一个对象来调用。你需要将方法'a'和'b'声明为'static',以表明它们实际上是独立的函数,而不是类的方法。


顺便说一下,你能解释一下“指向方法”的指针和“指向函数”的指针有什么区别吗? - Roy Huang
2
函数的所有参数都是显式的。因此,您只需要调用指针本身和在函数签名中声明的参数即可调用函数。类的方法有一个隐藏的参数,在方法内部变成“this”。即为了调用方法,除了参数外,还需要兼容类型的对象。//function void foo(int x);auto fooptr = &foo; fooptr(1);class A{ public: void foo(int x); };auto afooptr = &A::foo; A obj; (obj.*afooptr)(1); - Konstantin Stupnik
1
静态方法从“指针”角度来看是一个函数。它不需要对象并且没有可用的“this”。 - Konstantin Stupnik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接