【问题标题】:Why is it disallowed for partial specialization in a non-type argument to use nested template parameters为什么不允许非类型参数中的部分特化使用嵌套模板参数
【发布时间】:2011-05-12 13:23:29
【问题描述】:

我有这个代码

template<int N, bool C = true>
struct A;

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

// should work
A<25> a;

也就是说,对于可以被5 整除的数字N,编译器应该使用部分特化。但是编译器不会接受这种部分特化,因为标准要求它拒绝这样的代码,其中部分特化的非类型参数引用参数而不是简单的参数(例如,A&lt;N, N&gt; 将是有效的)。但是这样做的原因是什么?

请注意,我可以简单地将我的代码更改为更冗长的示例并且它是有效的

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;

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

【问题讨论】:

  • 即使这样也是不允许的:ideone.com/Vxx0R ...我想知道标准中的哪个部分不允许这样做。 §14.5.4/9 也适用于此?
  • 这几乎是一样的,当你可以将它们包装在一个结构中时,为什么没有部分函数规范?
  • 你为什么还要在这段代码中使用模板?

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


【解决方案1】:

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

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

【讨论】:

  • @iammilind 从 C++14 和 MSVC2017 开始,这仍然是被禁止的。虽然不知道 C++17 和即将发布的草案
【解决方案2】:

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

此时

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

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

你的例子实例化了一个 using

A<25> a;

但你也可以拥有

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

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

【讨论】:

  • 我不关注。它知道N,因为你在说它是什么。现在是 25 或 15。
  • 部分特化的使用告诉编译器对第二个参数使用单个特定的实例化。但是这里 A 和 A 是不同的类型,所以会有不止一个实例化。
  • 对不起,我不明白你在说什么。是的,A&lt;25&gt;A&lt;15&gt; 是不同的类型,这和专业化有什么关系?
  • 这对我来说也没有意义。
  • -1:部分特化告诉编译器在遇到一组匹配的模板参数时使用单个特定的定义。然后,此定义将为每组匹配的模板参数生成不同的实例化(以与通用模板定义相同的方式)。只有完整的特化会生成一个实例化。
猜你喜欢
  • 1970-01-01
  • 2011-02-02
  • 1970-01-01
  • 1970-01-01
  • 2022-01-15
  • 2016-11-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多