简体   繁体   English

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

[英]Definition of standard-layout class in C++14

A standard-layout class is defined in [class]/7 in C++14, as follows (emphasis is mine): 标准布局类在C ++ 14的[class] / 7中定义,如下所示(重点是我的):

A standard-layout class is a class that: 标准布局类是一个类:

  • (7.1) — has no non-static data members of type non-standard-layout class (or array of such types) or reference, (7.1) - 没有类型为非标准布局类(或此类类型的数组)或引用的非静态数据成员,
  • (7.2) — has no virtual functions (10.3) and no virtual base classes (10.1), (7.2) - 没有虚函数(10.3),没有虚基类(10.1),
  • (7.3) — has the same access control (Clause 11) for all non-static data members, (7.3) - 对所有非静态数据成员具有相同的访问控制(第11条),
  • (7.4) — has no non-standard-layout base classes, (7.4) - 没有非标准布局基类,
  • (7.5) — either has no non-static data members in the most derived class and at most one base class with non-static data members, or has no base classes with non-static data members, and (7.5) - 在大多数派生类中没有非静态数据成员, 并且最多只有一个具有非静态数据成员的基类,或者没有具有非静态数据成员的基类,并且
  • (7.6) — has no base classes of the same type as the first non-static data member. (7.6) - 没有与第一个非静态数据成员相同类型的基类。

My concern is in relation to bullet (7.5): how is it possible to have no non-static data members in the most derived class and at the same time having one base class with non-static data members? 我关注的是bullet(7.5):如何在最派生的类中没有非静态数据成员,同时有一个基类具有非静态数据成员?

In other words, aren't the non-static data members of the base class, also non-static data members of the most-derived class? 换句话说,不是基类的非静态数据成员,也是最派生类的非静态数据成员?

Yes, this is a defect in C++14, specifically CWG 1813 . 是的,这是C ++ 14中的一个缺陷,特别是CWG 1813 Although it can be repaired by reading "non-static data members" to refer only to direct (non-inherited) non-static data members (as is probably necessary elsewhere), the chosen fix has been to replace the language you found problematic with the following: 虽然可以通过读取“非静态数据成员”来仅修复直接 (非继承)非静态数据成员(在其他地方可能是必要的)来修复它,但所选择的修复方法是替换您发现的有问题的语言。下列:

A standard-layout class is a class that: [...] 标准布局类是一个类:[...]

  • has all non-static data members and bit-fields in the class and its base classes first declared in the same class, [...] 该类中的所有非静态数据成员和位字段及其基类首先在同一个类中声明,[...]

This is a little tricky to get right; 为了做到这一点,这有点棘手; there is some resistance to the idea of considering inherited members as members of the derived class, even though [class.derived] has: 尽管[class.derived]具有以下内容,但对将继承成员视为派生类成员的想法存在一些阻力:

[...] Unless redeclared in the derived class, members of a base class are also considered to be members of the derived class. [...]除非在派生类中重新声明,否则基类的成员也被视为派生类的成员。 Members of a base class other than constructors are said to be inherited by the derived class. 除了构造函数之外的基类的成员被称为由派生类继承 [...] [...]

Notwithstanding this, a number of places where both direct and inherited non-static data members are intended to be considered specifically call out inherited data members, for example also in [class] (after the resolution to CWG 1672 ): 尽管如此,许多直接和继承的非静态数据成员都被认为是专门调用继承数据成员的地方,例如也在[类]中 (在CWG 1672的决议之后):

8.6 - an aggregate or union type that includes one of the aforementioned types among its elements or nonstatic data members (including, recursively, an element or non-static data member of a subaggregate or contained union), 8.6 - 聚合或联合类型,包括其元素或非静态数据成员中的上述类型之一(递归地,包括子聚合或包含联合的元素或非静态数据成员),

Or in [basic.lval] : 或者在[basic.lval]中

7.8 - If X is a non-union class type, the set M(X) is empty if X has no (possibly inherited (Clause 10)) non-static data members; 7.8 - 如果X是非联合类类型,如果X没有(可能是继承的(第10条))非静态数据成员,则集合M(X)为空; [...] [...]

Meanwhile, in many places "members" has to be read as referring only to direct members to make sense; 同时,在许多地方,“成员”必须被解读为仅指直接成员才有意义; to begin with and only looking at non-static data members (not member functions), [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.copy]/12.2, /12.4, /18.2, /25.2, /25.4, /26.3, /27, [except.spec]/15.1.1.1, /15.2, /15.3 are all places where "non-static data members" could or should have "direct" prefixed. 首先,只查看非静态数据成员(不是成员函数),[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是“非静态数据成员”可以使用的所有地方或者应该有“直接”前缀。

On the other hand, in some places (eg in the amended [class], or in [class.copy]/23.2-23.3, /28) "members" is implicitly taken to include inherited members, so it's a bit of a mess. 另一方面,在某些地方(例如在修订的[class]或[class.copy] /23.2-23.3,/ 28)中,“成员”被隐含地包含在继承成员中,所以它有点混乱。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM