[英]Function template overload resolution, dependent and non-dependent parameters
给定以下程序
#include <iostream>
template<class T> struct id { using type = T; };
template<class T1, class T2>
int func(T1, T2) { return 0; }
template<class T1, class T2>
int func(typename id<T1>::type, typename id<T2>::type) { return 1; }
int main()
{
std::cout << func<int, int>(0, 0) << std::endl;
}
GCC 和 Clang 都为该程序打印1
。 这个程序是否保证按标准打印1
?
我试图在这里找到答案,但无法破译。 看起来 function 模板可能是等效的,因此会破坏 ODR,但我不确定。
是否将第二个 function 模板更改为
template<class T>
using id_type = typename id<T>::type;
template<class T1, class T2>
int func(id_type<T1>, id_type<T2>) { return 1; }
做出改变?
这是沼泽标准的部分排序。 我们将唯一类型替换为 function 模板之一,并尝试根据它推断出另一个。 双向进行,如果推论只在一个方向上成功,我们有一个命令。 如果您想阅读神秘的规则,请参阅 [temp.func.order] 和 [temp.deduct.partial]。
所以在这里,
T1=U1, T2=U2
代入第一个重载的 function 类型产生int f(U1, U2);
我们可以由此推断出第二次重载中的T1
和T2
吗? 不; 两者都在非推断的上下文中。 因此,推演失败。T1=U1, T2=U2
代入第二个重载会产生int f(id<U1>::type, id<U2>::type)
(这是在定义上下文中进行的,因此我们不能进一步代入id
-某处可能有专业化)。 我们可以由此推断出第一次重载中的T1
和T2
吗? 是的,通过推导T1 = id<U1>::type
和T2 = id<U2>::type
。 扣分成功。由于推导只在一个方向上成功——从转换后的第二个推导第一个——第二个比第一个更专业,并且优先被重载决议挑选。
别名模板案例没有任何改变。
这些模板既不等价,也不在功能上等价。
以下func
重载
// Denote as overload F. template<class T1, class T2> int func(typename id<T1>::type, typename id<T2>::type) { return 1; }
比下面的func
重载更专业
// Denote as overload G. template<class T1, class T2> int func(T1, T2) { return 0; }
因此,前者是通过重载决议选择的。
(以下所有 ISO 标准参考参考N4659:2017 年 3 月 Kona 后工作草案/C++17 DIS )
func
的G
和F
重载的部分排序受以下约束:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.