为什么不允许非类型参数中的部分特化使用嵌套模板参数

时间:2011-05-12 13:23:30

标签: c++ partial-specialization design-rationale

我有这段代码

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;

这很好,因为它不再是非类型参数。但是,规范禁止更直接的部分专业化的原因是什么?

2 个答案:

答案 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选择值?它不能,因此它必须禁止代码。