Overload Resolution and Explicit Template Arguments

The following code prints "func 2" .

Why does the compiler consider the second template to be the best match in the presence of explicit (not deduced) template arguments? Why is there no ambiguity?

I would appreciate quotes from the C ++ standard.

#include <iostream> template<class T> struct identity { typedef T type; }; template<class T> void func(T) { std::cout << "func 1\n"; } template<class T> void func(typename identity<T>::type) { std::cout << "func 2\n"; } int main() { func<int>(1); } 
+6
source share
1 answer

Both candidates are viable and accept the same arguments, so the overload resolution process returns to the last tie-break: partial order of function templates [temp.func. order] .

The rule is that we synthesize a new type for each parameter of the template type and try to subtract the mutual overload. For 1 we synthesize the type Unique1 , which does not output to 2 , because T is not a deducible context. For 2 we synthesize the type Unique2 , which outputs T = typename identity<Unique2>::type . Since deduction succeeds in one direction and not in the other, which makes 2 more specialized than 1 , so it will be preferred.

Please note that the rules for partial ordering of a template are somewhat incomplete in the standard. If you just add another argument of type T , preference is flipped .

+3
source

All Articles