【问题标题】:Are static members of a class template implicitly instantiated, or not?类模板的静态成员是否隐式实例化?
【发布时间】:2014-10-31 11:00:51
【问题描述】:

考虑以下两个引号:

[C++11: 14.7.1/1]: [..] 类模板特化的隐式实例化导致声明的隐式实例化,而不是定义或默认参数的隐式实例化类成员函数、成员类、作用域成员枚举、静态数据成员和成员模板; [..]

[C++11: 14.7.1/8]: 类模板的隐式实例化不会导致该类的任何静态数据成员被隐式实例化。

(在[C++14: 14.7.1/1][C++14: 14.7.1/9] 中也找到了逐字记录——除了对异常规范的新引用)

我在这里缺少什么?隐式实例化类模板和隐式实例化类模板特化有什么区别?这两个引号怎么不冲突?

[C++11: 14.7.1/5]: 如果在需要完全定义的对象类型的上下文中使用类类型,或者如果类类型的完整性可能影响程序的语义,则类模板特化会被隐式实例化。 [..]

【问题讨论】:

  • 除非我读错了,否则它们听起来并不冲突。第一个引号是:“...导致声明的隐式实例化,但不是...静态数据成员”。第二个引用也说明了这一点。
  • @Cyber​​:我认为你误读了。那将是一个非常奇怪且没有任何意义的句子结构:what 的“声明”?相反,我认为第一个引用表明 的声明(但不是定义)是隐式实例化的。第二个引用说 没有被隐式实例化。最简单的解决方案是 Angew 所说的:第二个引用缺少限定词“定义”。但就是这样,它不见了,所以现在引号冲突。
  • 哦,好吧,我认为“但不是”适用于声明的其余部分,但在重新阅读后,情况并非如此。

标签: c++ templates c++11 language-lawyer c++14


【解决方案1】:

我不认为引号实际上是冲突的。标准杆。 1 表示静态成员的声明是实例化的,但定义不是。标准杆。 8 表示该成员未实例化。由于某事的非定义声明并不是真正的某事,我会说他们说的是同一件事。标准杆。 8 或许可以澄清一下,包括“定义”一词。

以下是我认为支持我对 Par.8 的推理的一些引述(尽管不幸的是,它们都不是清晰的证据):

14.7/2 ... 一个成员函数,一个成员类,一个成员枚举, 或从类模板的成员定义实例化的类模板的静态数据成员 分别被称为实例化的成员函数、成员类、成员枚举或静态数据 会员。 ...

14.7.1/2 除非类模板或成员模板的成员已被显式实例化或显式 特化,当引用特化时,成员的特化被隐式实例化 在需要成员定义存在的上下文中;特别是,初始化(以及任何相关的 除非静态数据成员本身以某种方式使用,否则不会发生静态数据成员的副作用) 这需要静态数据成员的定义存在。

(全部取自 C++11,重点是我的)

对我来说,这意味着“实例化静态数据成员”实际上意味着“实例化静态数据成员的定义”。

【讨论】:

  • 听起来很合理。您可以通过任何先前的研究或一些邮件列表讨论或 DR 或其他东西来支持您的主张吗?并不是说我能找到任何-.-
  • @LightnessRacesinOrbit 不是真的,这只是我解析英文文本的方式。 "实例化 (mf, mc, sme, sdm, mt) 的 (Dec && !(Def || DefArg))
  • 哦,不,我认为第 1 段的那部分很清楚。我说的是第 8 段。虽然我同意您对它的解释,但 段的文本中没有任何内容可以实际证明这一点。
  • @LightnessRacesinOrbit 添加了一些我认为可以支持我的解释的引文。
  • 嗯似乎有点瘦:P我不确定你可以选择一个段落,将“静态数据成员”和“定义”这两个短语的每一次出现都加粗(无论它们落在哪里)收工:P
猜你喜欢
  • 2011-04-11
  • 1970-01-01
  • 2017-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多