Я пытаюсь понять, как профсоюзы были расширены C++ 11. Одна вещь, которая изменилась, - это возможность использовать теперь нестатические элементы данных с нетривиальными специальными функциями-членами. От cppreference.comСоюзы в C++ 11: конструктор по умолчанию, кажется, удален
Если объединение содержит нестатический элемент данных с нетривиальным специальной функцией члена (конструктором по умолчанию, копировать/перемещать конструктору, копировать/Переместить назначение или деструктора), эта функция будет удалена по умолчанию в союзе и должен быть определен явно программистом. Не более одного элемента данных может иметь инициализатор элемента по умолчанию.
Я пытаюсь следующий код:
struct X
{
~X() {};
};
union U
{
X x;
~U() {};
};
int main()
{
U s1{}; // works, probably aggregate initialization
U s2; // DOES NOT compile, why?
}
Здесь X
(который используется в качестве элемента данных объединения) имеет при условии пользователя деструктор, следовательно, деструктор объединение по умолчанию удаляется. Поэтому я предоставляю это явно. Тем не менее, код не компилировать с ошибкой
примечание: '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), соответствующий член func союз должен быть предоставлен пользователем или он будет неявно удален (8.4.3) для объединения. -endnote]
похоже, что это ошибка gcc (теперь сообщается here). Код компилируется на clang и gcc 4.8.2 или ранее, он разбивается на gcc4.9 и более поздние версии (спасибо @ T.C. для указания).
Компилятор: g ++ 5.3, -std=c++11
б/у.
[Clang] (http://coliru.stacked-crooked.com/a/b58a360400009fa9) вполне доволен этим кодом. На самом деле это похоже на ошибку GCC. –
@ T.C. Да, я действительно видел это только после вашего комментария. Я сначала сделал впечатление, что clang также отклонил его, возможно, была проверена некоторая модифицированная версия. Отредактировал последнюю строку вопроса, спасибо. – vsoftco
@ T.C. Я попытаюсь вникнуть в стандарт ... – vsoftco