Почему std :: is_aggregate <T>является агрегатом? - PullRequest
11 голосов
/ 23 апреля 2019

У меня всегда было впечатление, что типы типа std::is_same, std::is_void или std::is_aggregate должны наследоваться от std::integral_constant или, более конкретно, от std::bool_constant.

Однако у агрегатных классов не должно быть базового класса по определению , но когда я использую эти типы как T в std::is_aggregate_v<T>, я получаю true. Очевидно, что они не получены из std::bool_constant?

Итак, мой вопрос:

Почему std::is_aggregate_v<std::is_aggregate<void>> верно, по крайней мере, с GCC и Clang? Разве в стандарте не указано, что std::is_aggregate является производным от std::bool_constant? Если нет, значит ли это, что значение вышеприведенной строки остается в качестве подробности реализации?

Ответы [ 2 ]

11 голосов
/ 23 апреля 2019

Однако агрегатные классы не должны иметь базовый класс по определению

Это больше не так. [dcl.init.aggr] / 1 определяет агрегат как

Агрегат - это массив или класс с

  • нетпредоставленные пользователем, явные или унаследованные конструкторы ([class.ctor]),

  • нет частных или защищенных нестатических элементов данных (пункт [class.access]),

  • без виртуальных функций и

  • без виртуальных, частных или защищенных базовых классов ([class.mi]).

[Примечание. Совокупная инициализация не позволяет получить доступ к защищенным и закрытым членам или конструкторам базового класса.- конец примечания]

Больше нет условия, что у него нет базового класса, как в C ++ 14 и более ранних версиях.Пока у него есть открытый, не виртуальный базовый класс, который теперь разрешен.Это означает, что черты типа теперь считаются агрегированными, если для них справедливо вышеуказанное

3 голосов
/ 23 апреля 2019

Начиная с C ++ 17, классы с не виртуальными, не частными или защищенными базами являются агрегатами: https://en.cppreference.com/w/cpp/language/aggregate_initialization

...