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



以下程序打印T,T.

#include <iostream>
template<typename T>
void f(T x, T y) {
std::cout << "T,Tn";
}
template<typename T1, typename T2> 
void f(T1 x, T2 y) {
std::cout << "T1,T2n";
}
int main() {
f(1, 1); 
return 0;
}

哪个模板在代码中排在第一位没有区别。

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

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

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

对重载的函数模板执行部分排序以确定应选择哪一个。

当同一函数模板专用化匹配多个函数模板时 重载函数模板(这通常是由模板引起的 参数推导(,重载函数模板的部分排序 以选择最佳匹配项。

具体而言,部分排序发生在以下位置 情况:

1( 调用函数模板的重载解析 专业化

template<class X> void f(X a);
template<class X> void f(X* a);
int* p;
f(p);

2( ...

非正式地说,"A 比 B 更专业"意味着"A 接受的类型比 B 少"。

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

也许答案的一部分就在这里Implicit_instantiation

当代码引用上下文中需要函数定义的函数存在,并且此特定函数尚未显式实例化时,将发生隐式实例化。如果可以从上下文中推导出模板参数列表,则不必提供模板参数列表

编译器将调用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

相关内容

  • 没有找到相关文章

最新更新