Я пытаюсь понять, как профсоюзы были расширены С++ 11. Одна вещь, которая изменилась, - это возможность использовать теперь нестатические элементы данных с нетривиальными специальными функциями-членами. Из cppreference.com
Если объединение содержит нестатический элемент данных с нетривиальной специальной функцией-членом (конструктор по умолчанию, конструктор копирования/перемещения, назначение копирования/перемещения или деструктор), эта функция по умолчанию удаляется в объединении и требует который будет определен явно программистом. Не более одного элемента данных может иметь инициализатор элемента по умолчанию.
Я пытаюсь выполнить следующий код:
struct X
{
~X() {};
};
union U
{
X x;
~U() {};
};
int main()
{
U s1{}; // works, probably aggregate initialization
U s2; // DOES NOT compile, why?
}
Здесь X
(который используется как член данных объединения) имеет предоставленный пользователем деструктор, поэтому деструктор объединения по умолчанию удаляется. Поэтому я предоставляю это явно. Однако код не компилируется с ошибкой
note: 'U:: U()' неявно удаляется, потому что определение по умолчанию будет плохо сформировано:
Код компилируется, если я удаляю последнюю строку U s2;
.
Вопрос Что здесь происходит? Почему U s1{};
компилируется, но U s2;
нет? Является ли по умолчанию ctor союза помеченным как удаленное (если да, почему?!), и в первом случае мы имеем только агрегатную инициализацию? Обратите внимание, что если я предоставляю U(){}; // not U() = default;
, код компилируется (но не если я предоставляю только ctor X
).
ИЗМЕНИТЬ
После перехода в стандарт (N4527):
Союзы: 9.5/2 [class.union]
[Примечание: если какой-либо нестатический член данных объединения имеет нетривиальный конструктор по умолчанию (12.1), конструктор копирования (12.8), конструктор перемещения (12.8), оператор назначения копирования (12.8), оператор присваивания перемещения ( 12.8) или деструктор (12.4), соответствующая членская функция объединения должна быть предоставлена пользователем или она будет неявно удалена (8.4.3) для объединения. -endnote]
похоже, что это ошибка gcc (теперь сообщается здесь). Код компилируется на clang и gcc 4.8.2 или ранее, он разбивается на gcc4.9 и более поздние версии (спасибо @T.C. для указания).
Компилятор: g++ 5.3, -std=c++11
.