模板重载决议:当多个模板匹配时会发生什么?

Template overload resolution: what happens when multiple templates match?

以下程序打印 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;
}

代码中哪个模板先出现没有区别。

我希望重载决议在这里是模棱两可的。 TT1T2 都应推导为 int,这使得两个模板都与调用站点完全匹配。

我没能找到任何解析规则(https://en.cppreference.com/w/cpp/language/overload_resolution)来解释为什么它会选择第一个模板。

我用 clang++ -std=c++17 测试过,以防万一。

执行 overloaded function templates 的部分排序以确定应该选择哪一个。

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".

选择第一个重载是因为它只接受一种相同类型的参数,而第二个重载可以接受两种独立类型的参数。

也许这里有部分答案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

编译器将调用 f(1, 1) 与实例化 f<int> 连接起来。在代码中删除第一个模板 (template<typename T> void f(T x, T y)) 时,编译器将调用 f(1, 1) 与实例化 f<int, int> 连接起来。 您可以使用类型的显式指示来调用每个实例化:

f(1, 1);
f<int>(1, 1);
f<int, int>(1, 1);

输出为:

T,T
T,T
T1,T2