Инициализация агрегатов С++ 11 для классов с нестационарными инициализаторами элементов

Разрешено ли в стандарте:

struct A
{
  int a = 3;
  int b = 3;
};

A a{0,1}; // ???

Является ли этот класс еще агрегатом? clang принимает этот код, но gcc не делает.

Ответы

Ответ 1

В С++ 11 с инициализаторами члена класса делает struct/class не агрегированием — однако это было изменено на С++ 14. Это то, что я нашел удивительным, когда я впервые столкнулся с этим, объяснение этого ограничения заключается в том, что инициализаторы в классе очень похожи на пользовательский конструктор, но аргумент счетчика заключается в том, что никто не ожидает, что добавление инициализаторов в классе должно сделать их класс/структура не является агрегированным, я уверен, что нет.

Из черновик С++ 11 раздел 8.5.1 Агрегаты (выделение в будущем):

Агрегат - это массив или класс (раздел 9) без каких-либо пользовательских конструкторы (12.1), нет несимметричных инициализаторов для нестатических членов данных (9.2), нет частных или защищенных нестатических элементов данных (Раздел 11), нет базовых классов (раздел 10) и нет виртуальных функций (10.3).

и в С++ 14 этот же абзац гласит:

Агрегат - это массив или класс (раздел 9) без каких-либо пользовательских конструкторы (12.1), частные или защищенные нестатические элементы данных (Раздел 11), нет базовых классов (раздел 10) и нет виртуальных функций (10.3).

Это изменение описано в N3605: инициализаторы и агрегаты участников, которые имеют следующий реферат:

Бьярне Страуструп и Ричард Смит подняли вопрос об агрегировании инициализация и инициализаторы членов не работают вместе. Эта бумага предлагает исправить эту проблему, приняв предложенную Смитом формулировку который удаляет ограничение, которое агрегаты не могут иметь член-инициализаторы.

Этот комментарий в основном суммирует нежелание давать агрегаты:

Агрегаты не могут иметь определяемые пользователем конструкторы и Member-initializers - это, по существу, определенный пользовательский конструктор (элемент) (см. также Core Defect 886). Я не против этого расширение, но оно также имеет последствия для того, что наша модель агрегаты на самом деле есть. После принятия этого расширения я бы как знать, как научить, что такое совокупность.

Пересмотренная версия N3653 была принята в май 2013 г..

Обновить

emsr указывает, что g++ 5.0 теперь поддерживает агрегаты С++ 14 с инициализаторами нестатических элементов данных, используя либо std=c++1y, либо -std=c++14:

struct A { int i, j = i; };
A a = { 42 }; // a.j is also 42

Посмотрите, как работает в прямом эфире.