为什么这个派生类不是标准的布局类?

Lau*_*nis 2 c++ language-lawyer c++14 c++17

为什么bar不是标准的布局类型,在 C++17 下?

#include <type_traits>

class foo {
    int x;
};

static_assert(std::is_standard_layout<foo>::value);

class bar : public foo {
    float y;
};

static_assert(std::is_standard_layout<bar>::value); // "static assertion failed"
Run Code Online (Sandbox Code Playgroud)

基于CPP 参考描述一个非常相似的问题,我理解为什么在 C++14 之前这不是标准布局类型,但我无法连接CPP 参考的描述项目,通过排除其他所有内容,应该是这里应用的项目:“没有一个基类子对象具有与非联合类型相同的类型,作为第一个非静态数据成员(参见空基优化),并且递归地,该数据成员的第一个非静态数据成员(如果它有)非联合类类型,或者该数据成员的所有非静态数据成员(如果它具有联合类型),或者该数据成员的元素(如果它具有数组类型)等。”

wal*_*nut 7

bar在您引用的之前不满足要求(来自标准布局类的 cppreference.com 页面):

要求

  • [...]

  • 在同一个类中声明了所有非静态数据成员和位域(要么全部在派生类中,要么全部在某个基类中)

  • [...]

bar有一个直接的非静态数据成员float y;和一个int x;foo.


此特定要求的 C++14 以来的措辞(在大多数情况下?)在功能上等同于之前的措辞,并且在您链接的问题的答案中也提到了这一点。

更改只是因为措辞中可能存在误解,请参阅CWG 问题 1813并添加位字段,因为它们可能未包含在术语成员中,请参阅CWG 问题 1881