我有这段代码
template<int N, bool C = true>
struct A;
template<int N>
struct A<N, !(N % 5)> {
/* ... */
};
// should work
A<25> a;
也就是说,对于可以被N
整除的数字5
,编译器应该使用部分特化。但是编译器不接受部分特化,因为标准要求它拒绝这样的代码,其中部分特化的非类型参数引用参数而不仅仅是参数(例如,A<N, N>
将是有效的)。但是这样做的原因是什么?
请注意,我只需将我的代码更改为更加冗长的示例,它就是有效的
template<bool> struct wrap;
template<int N, typename = wrap<true> >
struct A;
template<int N>
struct A<N, wrap<!(N % 5)> > {
/* ... */
};
// should work
A<25> a;
这很好,因为它不再是非类型参数。但是,规范禁止更直接的部分专业化的原因是什么?
答案 0 :(得分:13)
我认为很多都是历史性的。最初不允许使用非类型模板参数。添加后,有批次的限制。当人们尝试不同的可能性并确认它们没有引起问题时,一些限制被删除了。
除了没有人愿意为改变它们而烦恼之外,其中一些原始限制仍然没有特别的原因。就像那里一样,它们中的许多都可以解决,所以通常经常去除它们不会造成任何特别的困难。这主要归结于一个问题,即是否有人关注这个特定的案例,写一篇关于它的论文。
答案 1 :(得分:-5)
部分特化要求在编译时可以解析非类型模板参数。
此时
template<int N>
struct A<N, !(N % 5)> {
/* ... */
};
N
是一个可以使用多个值的变量,编译器无法确定地计算N % 5
。
您的示例使用
实例化A<25> a;
但你也可以
A<25> a1;
A<15> a2;
在这种情况下,编译器如何为N选择值?它不能,因此它必须禁止代码。