Reputation: 178
The following program prints T,T
.
#include <iostream>
template<typename T>
void f(T x, T y) {
std::cout << "T,T\n";
}
template<typename T1, typename T2>
void f(T1 x, T2 y) {
std::cout << "T1,T2\n";
}
int main() {
f(1, 1);
return 0;
}
It makes no difference which template comes first in the code.
I would expect overload resolution to be ambiguous here. T
, T1
, and T2
should all be deduced as int
, which makes both templates match the call site exactly.
I haven't been able to find any resolution rules (https://en.cppreference.com/w/cpp/language/overload_resolution) to explain why it would choose the first template.
I tested with clang++ -std=c++17
, in case that matters.
Upvotes: 7
Views: 1391
Reputation: 236
Maybe a part of answer is here Implicit_instantiation
When code refers to a function in context that requires the function definition to exist, and this particular function has not been explicitly instantiated, implicit instantiation occurs. The list of template arguments does not have to be supplied if it can be deduced from context
The compiler connects call f(1, 1)
with instantiation f<int>
. When the first template (template<typename T> void f(T x, T y)
) is removed in the code, the compiler connects call f(1, 1)
with instantiation f<int, int>
.
You can call each instantiation using explicit indication of types:
f(1, 1);
f<int>(1, 1);
f<int, int>(1, 1);
output is:
T,T
T,T
T1,T2
Upvotes: 0
Reputation: 172924
Partial ordering of overloaded function templates is performed to determine which one should be selected.
When the same function template specialization matches more than one overloaded function template (this often results from template argument deduction), partial ordering of overloaded function templates is performed to select the best match.
Specifically, partial ordering takes place in the following situations:
1) overload resolution for a call to a function template specialization
template<class X> void f(X a); template<class X> void f(X* a); int* p; f(p);
2) ...
...
Informally "A is more specialized than B" means "A accepts fewer types than B".
The 1st overload is selected because it only accepts arguments with one same type, while the 2nd one could accept arguments with two independent types.
Upvotes: 7