【问题标题】:Compiler is unable to resolve a matching class method passed via std::mem_fn编译器无法解析通过 std::mem_fn 传递的匹配类方法
【发布时间】:2021-05-05 20:54:04
【问题描述】:

考虑the following code

struct A {
    int& getAttribute();
    const int& getAttribute() const;
};

std::vector<int> foo(const std::vector<A>& as) {
    std::vector<int> ints;
    std::transform(as.begin(), as.end(), std::back_inserter(ints),
                   std::mem_fn(&A::getAttribute));
    return ints;
}

其编译(g++ -std=c++14 -c mem_fn.cpp,g++ 版本 7.5.0)失败并出现以下错误:

error: no matching function for call to
‘mem_fn(<unresolved overloaded function type>)’

然而,

  • 如果我们keep只有const int&amp; getAttribute() const方法,编译成功
  • 如果我们keep 只使用int&amp; getAttribute() 方法,编译将失败并显示以下错误消息:
    /usr/include/c++/7/bits/stl_algo.h:4306:24:
         error: no match for call to
         ‘(std::_Mem_fn<int& (A::*)()>) (const A&)’
    /usr/include/c++/7/functional:174:27:
         error: no matching function for call to
         ‘__invoke(int& (A::* const&)(), const A&)’
    /usr/include/c++/7/bits/invoke.h:89:5:
         error: no type named ‘type’ in
         ‘struct std::__invoke_result<int& (A::* const&)(), const A&>’
    

或者,我们可以在这里使用 lambda 或通过 explicitly specifying 匹配方法的类型作为 mem_fn 的模板参数来帮助编译器: std::mem_fn&lt;const int&amp; () const&gt;(&amp;A::getAttribute).

因此,看起来,由于 int&amp; getAttribute() 方法不适合,const int&amp; getAttribute() const 方法应该由编译器在原始代码中选择。 为什么编译器选择失败并报&lt;unresolved overloaded function type&gt;错误?

【问题讨论】:

    标签: c++ templates overloading member-function-pointers overload-resolution


    【解决方案1】:

    编译器应该在mem_fn创建时选择函数的指针。它只能查看std::mem_fn(&amp;A::getAttribute) 表达式,而无法查看它是如何使用的。可以使用 user-defined conversion operators 解决,但通常不会这样做。

    因此,您关于此mem_fn 未来用途的推理不适用。

    您必须指定&amp;A::getAttribute 的确切重载才能使用。将static_cast 转换为固定类型将起作用(这是允许未解析的重载函数的特殊情况):

      std::transform(
          as.begin(), as.end(), std::back_inserter(ints),
          std::mem_fn(static_cast<const int &(A::*)() const>(&A::getAttribute)));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-22
      • 2013-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-30
      • 1970-01-01
      相关资源
      最近更新 更多