This is the more sophisticated question mentioned in How does overload resolution work when an argument is an overloaded function?
Below code compiles without any problem:
void foo() {}
void foo(int) {}
void foo(double) {}
void foo(int, double) {}
// Uncommenting below line break compilation
//template<class T> void foo(T) {}
template<class X, class Y> void bar(void (*f)(X, Y))
{
f(X(), Y());
}
int main()
{
bar(foo);
}
It doesn't appear a challenging task for template argument deduction - there is only one function foo()
that accepts two arguments. However, uncommenting the template overload of foo()
(which still has just a single parameter) breaks compilation for no obvious reason. Compilation fails both with gcc 5.x/6.x and clang 3.9.
Can it be explained by the rules of overload resolution/template argument deduction or it should be qualified as a defect in those compilers?
As noted in the answer to your linked question:
Since the overload set contains a function template, the parameter is treated as a non-deduced context. This causes template argument deduction to fail:
And this failed deduction gives you your error. Note that if you explicitly specify the arguments, the code compiles successfully:
Live demo