Mes*_*kon 8 c++ templates language-lawyer c++17
鉴于以下程序
#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;
}
Run Code Online (Sandbox Code Playgroud)
GCC 和 Clang 都打印1了这个程序。这个程序是否保证1按标准打印?
我试图在这里找到答案,但无法破译。看起来函数模板可能是等效的,因此会破坏 ODR,但我不确定。
是否将第二个函数模板更改为
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; }
Run Code Online (Sandbox Code Playgroud)
做出改变?
这是沼泽标准的部分排序。我们将唯一类型替换到其中一个函数模板中,并尝试根据它推断出另一个。两种方法都可以,如果推论只在一个方向成功,我们就有了一个命令。如果您想阅读晦涩难懂的规则,请参阅 [temp.func.order] 和 [temp.deduct.partial]。
所以在这里,
T1=U1, T2=U2第一个重载的函数类型会产生:int f(U1, U2);我们可以由此推导出第二个重载中的T1and吗?T2不; 两者都处于非演绎上下文中。因此,推演失败。T1=U1, T2=U2第二个重载会产生int f(id<U1>::type, id<U2>::type)(这是在定义上下文中进行的,因此我们无法进一步代入id- 某处可能有专门化)。我们可以从中推导出第一个重载中的T1and吗?T2是的,通过推导T1 = id<U1>::type和T2 = id<U2>::type。推演成功。由于推导仅在一个方向上成功 - 从转换后的第二个方向推导第一个 - 第二个比第一个更专业,并且由重载解析优先选择。
别名模板大小写没有任何改变。
这些模板既不等效也不在功能上等效。
| 归档时间: |
|
| 查看次数: |
132 次 |
| 最近记录: |