Является ли тип POD в точности эквивалентным тривиальному типу стандартной компоновки?

22

В C ++ 20 концепция POD устарела, предположительно потому, что это бессмысленная составная черта тривиальности и стандартной компоновки. Однако определение POD в проекте C ++ 20 не совсем «тривиально и стандартно»; это на самом деле:

Класс POD - это класс, который является как тривиальным классом, так и классом стандартной компоновки и не имеет нестатических членов-данных типа не-POD класса (или их массива). Тип POD - это скалярный тип, класс POD, массив такого типа или cv-квалифицированная версия одного из этих типов.

Другими словами, POD-тип не только является тривиальным и стандартным макетом, но и рекурсивным.

Является ли это рекурсивное требование излишним? Другими словами, если тип является как тривиальным, так и стандартным макетом, будет ли он автоматически рекурсивно тривиальным и стандартным макетом? Если ответ «нет», то каков пример стандартного макета, тривиального типа, который не может быть POD?

Брайан
источник

Ответы:

12

В C ++ 20 концепция POD устарела, предположительно потому, что это бессмысленная составная черта тривиальности и стандартной компоновки.

Неправильно. Термин POD является устаревшим, потому что он больше не имеет значения :

Термин POD больше не служит цели в стандарте, он просто определен, и ограничения применяются, когда несколько других типов сохраняют это рудиментарное свойство.

По сути, тип, который является как тривиальным, так и стандартным макетом, не приобретает никаких возможностей, помимо того, что тривиальный и стандартный макет предоставляют сами по себе. Сочетание этих двух типов не делает тип особенным, и эти два свойства не имеют большого отношения друг к другу.

Стандартная компоновка заключается в том, что компоновка непустых подобъектов является четко определенной (а также пустых подобъектов базового класса, не нарушающих компоновку типа). Тривиальность заключается в том, имеет ли объект какое-либо значение за пределами блока битов, которые он хранит (и является ли он концептуально допустимым объектом, если он инициализирован произвольным блоком битов).

Если я делаю шаблон, который принимает тип T, и я хочу посмотреть, смогу ли я memcpyобъекты этого типа, меня не волнует расположение его членов; Я хочу знать, если это TriviallyCopyable. Точно так же правильность значения offsetofне имеет значения, если в классе имеется предоставленный пользователем конструктор копирования. Все, что его волнует, - это если расположение подобъектов-членов происходит в четком стандартном порядке.

По сути, люди оглянулись и поняли, что в C ++ не осталось ничего такого, что конкретно требовало бы пересечения тривиальности и компоновки стандартов. Поэтому нам не нужно резервировать срок для этого. Те немногие места, где в стандарте прямо указано, что некоторый тип будет «POD», могут быть просто заменены «тривиальной и стандартной компоновкой», в зависимости от ситуации.

Является ли это рекурсивное требование излишним?

Поскольку оба составляющих требования являются индивидуально рекурсивными, пересечение двух также является рекурсивным. Таким образом, нет необходимости указывать, что все подобъекты также являются POD. Скорее всего, это был случай нечетного копирования и вставки, когда в оригинальном определении говорилось что-то вроде «все нестатические члены данных должны быть POD-типа», и они просто сохранили это утверждение как есть.

Николь Болас
источник
« Все, что его волнует, - это если расположение подобъектов-членов происходит в четком, стандартном порядке ». Почему стандартное устройство должно принудительно применять порядок, чтобы иметь возможность определять смещение члена? Это цель стандартного стандарта, чтобы позволить сумасшедшему, где члены не имеют смещения?
любопытный парень
1

Стандартная компоновка зависит от стандартной компоновки нестатических элементов:

[Class.prop]

Класс S является классом стандартной компоновки, если он:

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

  • ...

Тривиальность также зависит от тривиальности нестатических элементов. Для краткости я процитировал только правило для конструктора по умолчанию, но другие специальные функции-члены имеют похожую формулировку:

[Class.default.ctor]

Конструктор по умолчанию тривиален, если он не предоставлен пользователем и если:

  • ...
  • для всех нестатических членов данных своего класса, которые имеют тип класса (или его массив), каждый такой класс имеет тривиальный деструктор.

Насколько я могу судить, явное требование PODness для применения к элементам является излишним, поскольку оно также неявно следует из требований быть стандартным макетом и тривиальным.

eerorika
источник