The Problem
Please bear with me, this is really just an example:
#include <algorithm>
#include <iterator>
struct foo {
static int my_transform(int x) { return x;}
static std::vector<int> my_transform(std::vector<int> x){
std::vector<int> result;
std::transform(x.begin(),x.end(),std::back_inserter(result),my_transform);
return result;
}
};
What I expect to happen
There are two possible overloads for my_transform
, but only one results in a well-formed template instantiation, while for the other the template instantiation is ill-formed. I would expect the ill-formed one to be discarded and the above to compile.
What really happens
main.cpp:165:75: error: no matching function for call to
‘transform(std::vector<int>::iterator, std::vector<int>::iterator,
std::back_insert_iterator<std::vector<int> >, <unresolved overloaded function type>)’
std::transform(x.begin(),x.end(),std::back_inserter(result),my_transform);
^
How to fix it
Casting the function pointer to the right type resolves the ambiguity and it compiles:
static std::vector<int> foo::my_transform(std::vector<int> x){
std::vector<int> result;
typedef int (*my_transform_t)(int);
std::transform(x.begin(),
x.end(),
std::back_inserter(result),
static_cast<my_transform_t>(my_transform));
return result;
}
The Question
What exactly prevents the compiler from choosing the "correct" overload? Considering that only one can result in a valid template instantiation there isnt really a ambiguity.
PS: Note that this is C++98. In C++11 and beyond, the problem can be easily avoided by using lambdas (thanks to @appleapple for pointing that out).