C ++中标准布局类的定义14

时间:2016-10-06 19:23:27

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

标准布局类在C ++ 14的[class] / 7中定义,如下所示(重点是我的):

标准布局类是一个类:

  • (7.1) - 没有非标准布局类型的非静态数据成员 class(或此类型的数组)或引用,
  • (7.2) - 没有虚函数(10.3)且没有虚基类 (10.1),
  • (7.3) - 对所有非静态的访问控制(第11条) 数据成员,
  • (7.4) - 没有非标准布局基类,
  • (7.5) - 要么派生得最多,要么没有非静态数据成员 class 最多只有一个具有非静态数据成员的基类,或者有 没有带有非静态数据成员的基类,
  • (7.6) - 没有与第一个非静态相同类型的基类 数据成员。

我关注的是子弹(7.5):如何在最派生的类中拥有 no 非静态数据成员,同时有一个基类与非静态数据成员?

换句话说,不是基类的非静态数据成员,也是最派生类的非静态数据成员?

1 个答案:

答案 0 :(得分:8)

是的,这是C ++ 14中的一个缺陷,特别是CWG 1813。虽然它可以通过阅读"非静态数据成员"来修复。要仅引用直接(非继承)非静态数据成员(在其他地方可能是必要的),所选择的修复方法是用以下内容替换您发现有问题的语言:

  

标准布局类是一个类:[...]

     
      
  • 该类中的所有非静态数据成员和位字段及其基类首先在同一个类中声明,[...]
  •   

要想做对,这有点棘手;尽管 [class.derived] 具有:

,但是对于将继承成员视为派生类成员的想法存在一些阻力。
  

[...]除非在派生类中重新声明,否则为基类的成员   也被认为是派生类的成员。除了构造函数之外的基类的成员被派生类称为继承。 [...]

尽管如此,许多直接和继承的非静态数据成员都应该被认为是专门调用继承数据成员的地方,例如在 [class] 中(在解决之后)到CWG 1672):

  

8.6 - 聚合或联合类型,包括其元素或非静态数据成员中的上述类型之一(包括递归地,子聚合或包含联合的元素或非静态数据成员),

[basic.lval]

  

7.8 - 如果X是非联合类类型,如果X没有(可能是继承的(第10条)),则集合M(X)为空   非静态数据成员; [...]

同时,在很多地方"成员"必须被解读为仅指直接成员有意义;首先,只查看非静态数据成员(不是成员函数),[expr.rel] /3.2,[expr.const] /5.1,[dcl.constexpr] /4.6,[class.mem] / 17, / 19,[special] / 5,[class.ctor] /4.3,/4.4,/ 4.10,/ 4.12,[class.dtor] /5.6, [class.base.init] / 2,/ 13.3,[class。复制] /12.2,/ 12.4,/ 18.2,/ 25.2,/ 25.4,/ 26.3,/ 27,[except.spec] /15.1.1.1,/15.2,/15.3是"非静态数据的所有地方成员"可能或应该有"指导"前缀。

另一方面,在某些地方(例如在修订的[类],或[class.copy] /23.2-23.3,/ 28)"成员"隐含地被认为包含了继承的成员,所以它有点混乱。