Подтвердить что ты не робот

Почему класс со ссылками не придерживается standard_layout?

Выполнение следующего кода:

#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 также похожа.

4b9b3361

Ответ 1

Точка стандартной концепции стандартного класса компоновки С++ заключается в том, что экземпляр такого класса может быть надежно доступен или скопирован в байты, который, как отмечает стандарт С++ 11 в его § 9/9, делает такой класс

", полезный для общения с кодом, написанным на других языках программирования

Однако стандарт С++ не требует ссылки на использование хранилища вообще. Это не предмет. Вы не можете принять его адрес. Поэтому он не может быть (надежно) скопирован в байты или доступен как байты. И поэтому он несовместим с понятием стандартных классов макета.

В формальном,

С++ 11 §9/7:

" Класс стандартного макета - это класс, который:
- не имеет нестатических элементов данных типа нестандартного макета (или массива таких типов) или ссылки,

Ответ 2

Я не знаю, откуда вы получили эту цитату, но она не принимает соответствующее правило из стандарта.

(N3337) [class]/7: Класс стандартного макета - это класс, который:

- не имеет нестатических элементов данных типа нестандартного макета (или массива таких типов) или ссылки,

- не имеет виртуальных функций (10.3) и виртуальных базовых классов (10.1),

- имеет тот же контроль доступа (раздел 11) для всех нестатических членов данных,

- не имеет базовых классов нестандартной компоновки,

- либо не имеет нестатических элементов данных в самом производном классе и не более одного базового класса с нестатические члены данных или не имеет базовых классов с нестатическими элементами данных и

- не имеет базовых классов того же типа, что и первый нестатический элемент данных .108

Ответ 3

В n4140 вы можете прочитать:

9 Классы (7.1)

Класс стандартного макета - это класс, который:

  • не содержит нестатических элементов данных класса нестандартного макета (или массива таких типов) или ссылки,

[править]

для получения дополнительной информации о том, почему класс со ссылками не является стандартным макетом, прочитайте этот отличный ответ: Стандартная компоновка и ссылки на С++