【问题标题】:Why is in-class partial specialization well-formed?为什么课堂上的部分专业化形成良好?
【发布时间】:2016-11-17 14:00:01
【问题描述】:

根据 [temp.class.spec] 5/(强调我的)

可以声明或重新声明类模板的部分特化 在相应的主模板可以在其中的任何命名空间范围中 被定义

这表明部分特化(就像显式特化一样)必须出现在命名空间范围内。这实际上已被该段下方的示例所证实:

template<class T> struct A {
     struct C {
          template<class T2> struct B { };
     };
};
// partial specialization of A<T>::C::B<T2>
template<class T> template<class T2>
     struct A<T>::C::B<T2*> { };

//...
A<short>::C::B<int*> absip; // uses partial specialization

另一方面,C++ Standard Core Language Active Issues No 727 示例表明类内部分特化是良好的:

struct A {
  template<class T> struct B;
  template <class T> struct B<T*> { }; // well-formed
  template <> struct B<int*> { }; // ill-formed
};

我确定这里的核心问题文档是正确的,但找不到合适的参考来确认这一点。你能帮帮我吗?

【问题讨论】:

  • "模板可以在类或类模板中声明;这样的模板称为成员模板。"。回想一下,部分特化本身就是模板。
  • @JohannesSchaub-litb 但是为什么它不适用于显式专业化呢?它们不也是模板吗?
  • 你想通了。它们不是模板。它们是类或函数或变量。
  • @JohannesSchaub-litb 这是有道理的...如果您找到合适的规范片段,我会接受答案
  • @JohannesSchaub-litb 类、函数和变量也可以在类模板中声明,不是吗?

标签: c++ templates language-lawyer template-specialization partial-specialization


【解决方案1】:

意图是它是有效的——见N4090

在 2014 年 Issaquah 上对 DR 17557 和 DR 7278 进行了简要讨论,并基于对核心反射器的讨论91011,似乎 Core 正在针对成员模板及其特化遵循以下规则:部分特化和显式特化可以优先 声明在 innermost-enclosure-class 范围 或封闭 命名空间范围(认识到明确声明的特化 不构成向类添加成员,因此可以完成 在右大括号之后)。

7 http://www.open­std.org/jtc1/sc22/wg21/docs/cwg_toc.html#727
8 http://www.open­std.org/jtc1/sc22/wg21/docs/cwg_toc.html#1755
9http://accu.org/cgi­bin/wg21/message?wg=core&msg=24366(24033、24290、24309、24368)
10 http://accu.org/cgi­bin/wg21/message?wg=core&msg=24731(24731, 24732, 24736, 24738)
11http://accu.org/cgi­bin/wg21/message?wg=core&msg=25168 (25168-25179)

我提交了一个核心问题,因为我觉得目前的措辞不够清晰;您引用的段落可以被解释为不允许类内部分专业化。

【讨论】:

  • 您的意思是回答this 的问题吗?因此,由于template &lt;class T&gt; Foo::Bar&lt;T&gt; 的特化形式良好,派生类中 Bar 的类内特化也应该有效?
  • @W.F.不,我不认为我打算回答这个问题。
  • 抱歉,混淆了...需要更深入地检查
  • 不确定你答案的第一句话,但引用的文字肯定回答了我的问题!非常感谢您!
  • @W.F.你不确定什么?措辞要么未充分说明,因为 [temp.class.spec]/5 仅给出了充分条件(但不是必要条件),要么有缺陷,因为所表达的条件完全错误。
【解决方案2】:

规范在 14.5.2p1 中说

模板可以在类或类模板中声明;这样的模板称为成员模板。

14.5.5p2

每个类模板部分特化都是一个不同的模板,应为模板部分特化的成员提供定义

因此,类模板偏特化是一个模板,这也是自然的,因为它仍然有不固定的参数,因此它表示“类族”。模板可以在类或类模板中声明。

【讨论】:

  • 这个定义让我很困扰——你可以专门化模板,但你不能专门化专门化的模板,即使它是一个模板......
  • @W.F.我认为这件事有点微妙:“主类模板声明是类模板名称是标识符的声明。类模板名称是 simple-template-id 的模板声明是以 simple-template-id 命名的类模板。”。因此,主模板和任何部分特化都是同一个“类模板”的声明。只是一个是“初级”,另一个是“部分专业化”。然后这两个又是单独的模板。
  • 所以,我想有时当我们说我们可以“专门化一个模板”时,人们会在模板名称的意义上谈论“模板”,没有任何参数。而在其他时候,当人们谈论“类模板”时,人们会谈论类模板的具体定义:要么是主要的,要么是部分专业化之一。
  • 由于这似乎没有多大意义,我认为另一种解释“类模板名称为 simple-template-id 的模板声明是类模板的部分特化在 simple-template-id 中命名。”就是将其读作“by simple-template-id 命名的类模板”。回想一下 simple-template-id 看起来像 "Foo" 并且类模板在概念上是一个类族。在这个视图中,特化的类模板不是“Foo”,而是“Foo”。
  • 很好的解释!谢谢 - 我觉得我从你的答案/cmets中学到了很多......不幸的是,我觉得我无法判断哪个答案更好,因为它们对我都很有价值。我会等你在这件事上达成一些共识……
猜你喜欢
  • 2015-10-07
  • 1970-01-01
  • 2012-11-02
  • 1970-01-01
  • 1970-01-01
  • 2021-12-22
  • 1970-01-01
  • 1970-01-01
  • 2011-04-04
相关资源
最近更新 更多