Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template overload resolution: what happens when multiple templates match?

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.

like image 226
ppm Avatar asked Sep 27 '19 06:09

ppm


1 Answers

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.

like image 141
songyuanyao Avatar answered Nov 21 '22 16:11

songyuanyao