编译器无法解析通过 std::mem_fn 传递的匹配 class 方法
Compiler is unable to resolve a matching class method passed via std::mem_fn
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& getAttribute() const
方法,编译成功
- 如果我们keep只有
int& 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<const int& () const>(&A::getAttribute)
.
所以,看起来,由于 int& getAttribute()
方法不适合,const int& getAttribute() const
方法应该是编译器在原始代码中选择的方法。
为什么编译器无法 select 它并报告 <unresolved overloaded function type>
错误?
编译器应该在 mem_fn
创建时选择函数的指针。它只能查看 std::mem_fn(&A::getAttribute)
表达式,但不能查看它的使用方式。可以使用 user-defined conversion operators 解决,但通常不会这样做。
因此,您关于此 mem_fn
未来用途的推理不适用。
您必须指定要使用的 &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)));
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& getAttribute() const
方法,编译成功 - 如果我们keep只有
int& 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<const int& () const>(&A::getAttribute)
.
所以,看起来,由于 int& getAttribute()
方法不适合,const int& getAttribute() const
方法应该是编译器在原始代码中选择的方法。
为什么编译器无法 select 它并报告 <unresolved overloaded function type>
错误?
编译器应该在 mem_fn
创建时选择函数的指针。它只能查看 std::mem_fn(&A::getAttribute)
表达式,但不能查看它的使用方式。可以使用 user-defined conversion operators 解决,但通常不会这样做。
因此,您关于此 mem_fn
未来用途的推理不适用。
您必须指定要使用的 &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)));