【问题标题】:Why a class with references does not adhere to standard_layout?为什么带有引用的类不遵守标准布局?
【发布时间】:2016-07-21 03:00:17
【问题描述】:

执行以下代码:

#include <iostream>
#include <type_traits>

struct s_ref {
    int &foo;
};

struct s_ptr {
    int *foo;
};

int main(int argc, char *argv[])
{
    std::cout << "s_ref is_standard_layout:" << std::is_standard_layout<struct s_ref>::value << std::endl;
    std::cout << "s_ptr is_standard_layout:" << std::is_standard_layout<struct s_ptr>::value << std::endl;
    return 0;
}

结果:

s_ref is_standard_layout:0
s_ptr is_standard_layout:1

基于标准布局的使用(即:“标准布局类型对于与用其他编程语言编写的代码进行通信很有用”)这是有道理的,但我不确定违反了哪个规则:

标准布局类是一个类(用类、结构或 工会):

  • 没有虚函数,也没有虚基类。

  • 对其所有非静态数据成员具有相同的访问控制(私有、受保护、公共)。

  • 要么在派生最多的类中没有非静态数据成员,并且最多有一个具有非静态数据成员的基类,要么没有 具有非静态数据成员的基类。

  • 它的基类(如果有的话)本身也是一个标准布局类。

  • 并且,没有与其第一个非静态数据相同类型的基类 会员。

编辑:引用来自:http://www.cplusplus.com/reference/type_traits/is_standard_layout/,但http://en.cppreference.com/w/cpp/concept/StandardLayoutType 也类似。

【问题讨论】:

  • 你的报价来源是什么?
  • @Cheersandhth.-Alf 可能是cplusplus.com.
  • Cppreference 已修复..(我们肯定犯了错误,我想知道其他人是否抄袭了我们的)。你仍然可以争辩说它是正确的,因为它说的是标量或类,其成员是标准布局。引用类型不是标量或类。

标签: c++


【解决方案1】:

C++ 标准的标准布局类概念的要点在于,此类类的实例可以作为字节可靠地访问或复制到字节,正如 C++11 标准所指出的那样在其第 9/9 节中,创建了这样一个类

有助于与其他编程语言编写的代码进行交流

但是,C++ 标准根本不需要引用来使用存储。它不是一个对象。你不能拿它的地址。所以它不能(可靠地)复制到字节,或作为字节访问。因此它与标准布局类的概念不兼容。

在正式场合,

C++11 §9/7:

标准布局类是一个类:
— 没有非标准布局类(或此类类型的数组)或引用类型的非静态数据成员,

【讨论】:

  • 我认为这个答案比公认的更好,因为它实际上解释了基本原理,而不仅仅是跳上更正引用。
【解决方案2】:

我不知道你从哪里得到的那句话,但它错过了标准中的相关规则。

(N3337) [class]/7: 标准布局类是这样的类:

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

——没有虚函数 (10.3) 也没有虚基类 (10.1),

——对所有非静态数据成员具有相同的访问控制(第 11 条),

——没有非标准布局的基类,

——要么在最派生类中没有非静态数据成员,要么在最多一个基类中具有 非静态数据成员,或没有具有非静态数据成员的基类,并且

——没有与第一个非静态数据成员相同类型的基类。108

【讨论】:

    【解决方案3】:

    在 n4140 中您可以阅读:

    9 类 (7.1)

    标准布局类是这样的类:

    • 没有非标准布局类(或此类类型的数组)类型的非静态数据成员或参考

    [编辑]

    有关为什么带有引用的类不是标准布局的更多信息,请阅读这个出色的答案:C++ Standard Layout and References

    【讨论】:

      猜你喜欢
      • 2023-03-05
      • 1970-01-01
      • 2015-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多