Consider 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;
}
Its compilation (g++ -std=c++14 -c mem_fn.cpp, g++ version 7.5.0) fails with the following error:
error: no matching function for call to
‘mem_fn(<unresolved overloaded function type>)’
However,
- If we keep only the
const int& getAttribute() constmethod, the compilation succeeds - If we keep only the
int& getAttribute()method, the compilation fails with the following error messages:/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&>’
Alternatively, we could use a lambda here or help the compiler by explicitly specifying the type of a matching method as mem_fn's template argument:
std::mem_fn<const int& () const>(&A::getAttribute).
So, it looks like, as the int& getAttribute() method does not fit, the const int& getAttribute() const method is the one that should have been choosen by the by the compiler in the original code.
Why does compiler fail to select it and report the <unresolved overloaded function type> error?