40

我有这个代码

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;

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

4

2 回答 2

15

我认为很多都是历史性的。最初根本不允许使用非类型模板参数。添加它们时,有很多限制。随着人们尝试不同的可能性,并确认它们没有引起问题,一些限制被消除了。

除了没有人费心去改变它们的事实之外,这些最初的限制中的一些仍然没有特别的原因。就像那里一样,它们中的许多都可以解决,因此通常删除它们通常不会造成任何特别的困难。大多数情况下,它归结为一个问题,即是否有人足够关心这个特殊案例来写一篇关于它的论文。

于 2011-05-12T20:52:49.813 回答
-5

部分特化要求非类型模板参数在编译时是可解析的。

在此刻

template<int N>
struct A<N, !(N % 5)> {
  /* ... */
};

N是一个可以取多个值的变量,编译器无法N % 5确定地计算。

您的示例实例化了一个 using

A<25> a;

但你也可以有

A<25> a1;
A<15> a2;

在这种情况下,编译器如何为 N 选择一个值?它不能,因此它必须禁止该代码。

于 2011-05-12T16:12:02.163 回答