Объединения в С++ 11: конструктор по умолчанию, похоже, удаленC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Объединения в С++ 11: конструктор по умолчанию, похоже, удален

Сообщение Anonymous »


Я пытаюсь понять, как объединения были расширены в C++11. Единственное, что изменилось, — это возможность использовать теперь нестатические элементы данных с нетривиальными специальными функциями-членами. С сайта cppreference.com

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

Я пробую следующий код:

структура X { ~Х() {}; }; союз U { Х х; ~U() {}; }; интервал основной() { U s1 {}; // работает, вероятно, агрегатная инициализация У с2; // НЕ компилируется, почему? } Прямой эфир на Колиру

Здесь X (который используется как член данных объединения) имеет предоставленный пользователем деструктор, поэтому деструктор объединения по умолчанию удаляется. Поэтому я предоставляю его явно. Однако код не компилируется с ошибкой

примечание: 'U::U()' неявно удаляется, поскольку определение по умолчанию будет неверным:

Код компилируется, если я удалю последнюю строку U s2;.

Вопрос Что здесь происходит? Почему U s1{}; компилируется, а U s2; — нет? Дефолтный ctor объединения помечен как удаленный (если да, то почему?!), и в первом случае у нас просто агрегатная инициализация? Обратите внимание: если я предоставлю U(){}; // не U() = default; код компилируется (но не в том случае, если я предоставляю только вектор X).

ИЗМЕНИТЬ

Покопавшись в стандарте (N4527):

Союзы: 9,5/2 [class.union]

[Примечание: если какой-либо нестатический член данных объединения имеет нетривиальный конструктор по умолчанию (12.1), конструктор копирования (12.8), конструктор перемещения (12.8), оператор копирования копирования (12.8), оператор перемещения присваивания ( 12.8) или деструктор (12.4), соответствующая функция-член объединения должна быть предоставлена ​​пользователем, иначе она будет неявно удалена (8.4.3) для объединения. — сноска]

Похоже, что это ошибка gcc (сейчас об этом сообщается здесь). Код компилируется в clang и gcc 4.8.2 или более ранних версиях, он не работает в gcc4.9 и более поздних версиях (спасибо @TC за указание).

Используется компилятор: g++5.3, -std=c++11.
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»