Hol*_*olt 8 c++ template-specialization variadic-templates c++11
以下代码:
#include <cstddef>
template <size_t N,
typename T,
T first,
T... rest>
struct A {
};
template<typename T,
T... args>
struct A<0, T, args...> {
};
int main () {
A<0, int, 1> a0;
A<2, int, 1, 2> a2;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
... 由于以下原因而无法编译g++(版本5.1.0和5.3.0):
错误:部分特化并不比主模板更专业,因为它用包扩展替换了多个参数
...但是要编译clang.
是否允许宣布这种部分专业化?
旁注:实际上,专业化是危险的,因为A<0, int>无法使用两个编译器进行编译(模板参数数量错误).
gcc是正确的,代码格式不正确,因为专业化实际上并不是更专业化.
来自[temp.class.spec]的规则是(作为DR 1495的结果,链接的h/t TC):
在类模板部分特化的参数列表中,以下限制适用:[...]专业化应比主模板(14.5.5.2)更专业化.
为了确定这一点,我们将两个重写为合成函数模板:
template <size_t N, class T, T first, T... rest>
void __f(A<N, T, first, rest...> ); // primary
template <class T, T... args>
void __f(A<0, T, args...> ); // specialization
Run Code Online (Sandbox Code Playgroud)
然后完成部分排序规则.反过来,这涉及为每个模板参数合成新的类型/值,并查看演绎是否可以在任一方向上成功.
当然,专业化的推断因主要而失败(由于Nvs 0).在另一个方向,来自[temp.deduct.partial]:
如果
A从函数参数包转换而P不是参数包,则类型推导失败.
因为我们试图推断T first一个包,所以扣除也会在这个方向上失败.这意味着合成的函数模板都不比其他模板更专业,这反过来意味着类模板特化不比主模板更专业化.因此,gcc拒绝是正确的.
| 归档时间: |
|
| 查看次数: |
298 次 |
| 最近记录: |