为什么带引用的类不符合standard_layout?

时间:2016-04-01 10:30:32

标签: c++

执行以下代码:

#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

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

  

标准布局类是一个类(使用class,struct或   工会):

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

  •   
  • 对其所有非静态数据成员具有相同的访问控制(private,protected,public)。

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

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

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

  •   

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

3 个答案:

答案 0 :(得分:23)

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

  

对于与使用其他编程语言编写的代码进行通信非常有用

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

在正式中,

C ++11§9/ 7:
  

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

答案 1 :(得分:12)

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

  

(N3337) [class]/7:标准布局类是一个类:

     

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

     

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

     

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

     

- 没有非标准布局基类,

     

- 要么在派生类最多的类中没有非静态数据成员,要么最多只有一个基类   非静态数据成员,或者没有包含非静态数据成员的基类,

     

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

答案 2 :(得分:11)

在n4140中,您可以阅读:

9个班级(7.1)

  

标准布局类是一个类:

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

[编辑]

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