Почему этот производный класс не является стандартным классом макета? - PullRequest
2 голосов
/ 11 января 2020

Почему 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"

На основе CPP Справочное описание и очень похожий вопрос Я понимаю, почему это не стандартный тип макета до C ++ 14, но я не могу подключить CPP элемент описания ссылки , который, исключая все остальное, должен применяться здесь: «Ни один из подобъектов базового класса не имеет тот же тип, что и для типов без объединения, как первый элемент данных non-stati c (см. Пустая оптимизация базы) и, рекурсивно, первый элемент данных non-stati c этого члена данных, если он имеет тип класса, не являющийся объединением, или всех нестатических c членов данных этого члена данных, если он имеет тип объединения, или элемент этого члена данных, если он имеет тип массива, et c . "

1 Ответ

7 голосов
/ 11 января 2020

bar не соответствует требованию, указанному вами ранее (со страницы cppreference.com по стандартным классам макетов ):

Требования :

  • [...]

  • Содержит все нефиксированные c члены данных и битовые поля, объявленные в одном классе ( либо все в производном, либо все в некоторой базе)

  • [...]

bar имеет прямой не -stati c элемент данных float y; и унаследованный non-stati c элемент данных int x; от foo.


Формулировка C ++ 14 этого конкретного требования: (по большей части?) функционально эквивалентный предыдущему, что также было упомянуто в ответе на вопрос, который вы связали.

Он был изменен только из-за возможного недопонимания в формулировке, см. CWG выпуск 1813 и битовые поля были добавлены к нему, потому что они, возможно, не были включены в термин members , см. CWG выпуск 1881 .

...