Consider this example
#include <iostream>
template<class T>
void fun(T&){ //#1
std::cout<<"selected\n";
}
template<class T>
void fun(T&&){} //#2
int main() {
void(*ptr)(int&) = &fun; //#3
}
Both GCC and Clang report an error with the diagnosis "ambiguous". According to [temp.deduct.funcaddr#1], such two function templates are all viable in #3. Hence, [over.over#5] needs to apply here
Any given function template specialization F1 is eliminated if the set contains a second function template specialization whose function template is more specialized than the function template of F1 according to the partial ordering rules of [temp.func.order].
To judge which is more specialized between #1 and #2, [temp.deduct.partial#3.3] applies to them
The types used to determine the ordering depend on the context in which the partial ordering is done:
- [...]
- In other contexts the function template's function type is used.
Hence, the P and A used to participate in partial ordering should be the function type of that two function templates, respectively. Take the function type of #2 as P and the function type of #1 as A. Deduce P from A is successful as per [temp.deduct.type#10]
If P and A are function types that originated from deduction when taking the address of a function template ([temp.deduct.funcaddr]) or when deducing template arguments from a function declaration ([temp.deduct.decl]) and Pi and Ai are parameters of the top-level parameter-type-list of P and A, respectively, Pi is adjusted if it is a forwarding reference ([temp.deduct.call]) and Ai is an lvalue reference, in which case the type of Pi is changed to be the template parameter type (i.e., T&& is changed to simply T).
Conversely, Since we cannot deduce T& from T&&, hence the function template at #1 is more specialized than the function template at #2. Hence the specialization of #2 should be eliminated from the set. Ultimately, the set only contains exactly one specialization of #1. It should be unambiguous here. Why do GCC and Clang say the taking address is ambiguous?