C++11 агрегатная инициализация для классов с нестатическими инициализаторами элементов
Разрешено ли это в стандарте:
struct A
{
int a = 3;
int b = 3;
};
A a{0,1}; // ???
Является ли этот класс все еще агрегатным?
clang
принимает этот код, но gcc
не принимает.
1 ответ:
В C++11 наличие инициализаторов членов в классе делает структуру / класс не агрегатом - однако это было изменено в C++14. Это то, что я нашел удивительным, когда впервые столкнулся с этим, обоснование этого ограничения заключается в том, что инициализаторы в классе довольно похожи на пользовательский конструктор, но контраргумент заключается в том, что никто на самом деле не ожидает, что добавление инициализаторов в классе должно сделать их класс/структуру неагрегатной, я уверен, что нет.
Из проекта C++11 стандартный раздел
8.5.1
агрегаты (акцент мой идет вперед):Агрегат-это массив или класс (пункт 9) без указания пользователя. конструкторы (12.1), без скобок или равных инициализаторов для нестатических элементы данных (9.2) , нет закрытых или защищенных нестатических элементов данных (Пункт 11), никаких базовых классов (пункт 10) и никаких виртуальных функций (10.3).
И в C++14 тот же абзац гласит:
Агрегат-это массив или класс (пункт 9) без указания пользователя. конструкторы (12.1), без закрытых или защищенных нестатических элементов данных (Пункт 11), никаких базовых классов (пункт 10) и никаких виртуальных функций (10.3).
Это изменение описано в N3605: инициализаторы членов и агрегаты , который имеет следующий абстрактный вид:
Бьярне Страуструп и Ричард Смит подняли вопрос об агрегате инициализация и инициализаторы элементов не работают вместе. Этот документ предлагает исправить проблему, приняв предложенную Смитом формулировку. это устраняет ограничение, которое агрегаты не могут иметь инициализаторы членов .
Этот комментарий в основном подводит итог нежеланию позволять им быть агрегатами:
Агрегаты не могут иметь определяемые пользователем конструкторы и инициализаторы членов, по существу, являются своего рода определяемыми пользователем конструктор (элемент) (см. Также дефект ядра 886). Я не против этого. расширение, но оно также имеет последствия для того, что наша модель агрегаты на самом деле есть. После принятия этого расширения я бы хотелось бы знать, как научить, что такое совокупность.
Пересмотренный вариантN3653 был принят в мае 2013 года.
обновить
Emsr указывает, что G++ 5.0 теперь поддерживает агрегаты C++14 с инициализаторами нестатических элементов данных , используя либо
std=c++1y
, либо-std=c++14
:struct A { int i, j = i; }; A a = { 42 }; // a.j is also 42
Смотрите, как это работает [63]}жить .