POD类型是否完全等同于平凡的标准布局类型?

22
在C++20中,POD的概念已被弃用,据称这是因为它是一个无意义的复合特性,既具有trivial和standard-layout特性。然而,在C++20草案中POD的定义并不完全是“既trivial又standard-layout”,而实际上是:
``` POD类是既是trivial又是standard-layout的类,并且没有类型为non-POD类(或其数组)的非静态数据成员。POD类型是标量类型、POD类、此类类型的数组或其中一个的cv限定版本。 ```
换句话说,一个POD类型不仅是既trivial又是standard-layout,而且还是递归地这样。
这个递归要求是否多余?换句话说,如果一个类型既是trivial又是standard-layout,那么它自动地递归地也是trivial和standard-layout吗? 如果答案是“否”,那么有哪些既是trivial又是standard-layout的类型不是POD呢?
2个回答

13
在 C++20 中,POD 的概念已经被弃用,据称是因为它是一个毫无意义的复合特征,既具有平凡性又具有标准布局。然而,这是不正确的。之所以废弃 POD,是因为它 不再重要
POD 这个术语在标准中已经没有作用了,它只是被定义出来,在一些其他类型保留这种残留属性时会有限制。事实上,一个同时具有平凡性和标准布局的类型并不会获得任何超越平凡性和标准布局本身提供的能力。这两个属性的组合并不使该类型变得特殊,而且这两个属性实际上与彼此关系不大。
标准布局关注其非空子对象的布局是否被明确定义(以及它的空基类子对象是否不影响类型的布局)。平凡性则关注对象是否具有除存储的比特块之外的某些含义(以及如果使用任意比特块对其进行初始化是否在概念上是有效对象)。
如果我正在创建一个接受类型 T 的模板,并想知道是否可以使用 memcpy 复制该类型的对象,那么我不关心其成员的布局;我想知道它是否是 TriviallyCopyable。同样,offsetof 的正确性完全不关心类是否具有用户提供的复制构造函数。它所关心的只是成员子对象的布局是否以明确、遵循标准的顺序进行。
基本上,人们看了看发现,在C++中没有什么需要特别需要平凡和标准布局的交集。因此,我们不需要为此保留术语。标准明确说明某些类型将是“POD”的那些少数地方可以根据情况简单地替换为“平凡和标准布局”。
这个递归要求是否多余?
由于两个组成要求都是递归的,它们的交集也是递归的。因此,没有明确说明所有子对象也是POD的必要性。这很可能只是一个复制和粘贴的怪异现象,原始定义可能会说“所有非静态数据成员必须是POD类型”,然后他们就保留了该语句。

它所关心的只是成员子对象的布局是否按照明确的标准执行顺序。为什么std必须强制执行顺序才能确定成员的偏移量?std的目标是允许成员没有偏移量的疯狂实现吗? - curiousguy

2

标准布局的特性取决于非静态成员的标准布局:

[class.prop]

如果一个类S满足以下条件,则它是标准布局类:

  • 没有非标准布局类(或这些类型的数组)或引用类型的非静态数据成员,

  • ...

平凡性也取决于非静态成员的平凡性。为了简洁起见,我只引用了默认构造函数的规则,但其他特殊成员函数的措辞类似:

[class.default.ctor]

如果默认构造函数不是用户提供的并且满足以下条件,则它是平凡的:

  • ...
  • 对于其类中所有的非静态数据成员,如果该成员是类类型(或该成员的数组),则该类具有平凡析构函数。

据我所知,将POD性质明确要求适用于成员是多余的,因为它还隐含地遵循了标准布局和平凡性的要求。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接