Объединения в С++ 11: конструктор по умолчанию, похоже, удален ⇐ C++
-
Anonymous
Объединения в С++ 11: конструктор по умолчанию, похоже, удален
Я пытаюсь понять, как объединения были расширены в 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.
Я пытаюсь понять, как объединения были расширены в 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.
Мобильная версия