Вопросы, касающиеся С++ не-POD-союзов

С++ 11 дал нам возможность использовать не-POD-типы внутри союзов, например, у меня есть следующий фрагмент кода:

union
{
    T one;
    V two;
} uny;

Где-то внутри моего класса будет активен только один член, теперь мои вопросы довольно просты.

  • Что такое значение uny по умолчанию? - undefined?
  • Всякий раз, когда мой класс разрушается, какие члены (внутри союза), если они будут уничтожены?
    • Предположим, что мне нужно std:: typeinfo, чтобы отслеживать, кто является активным членом, должен ли я затем вызвать деструктор явно на этом члене в деструкторе?
  • Кто-нибудь имеет ссылку на предложение языка, которое изменило союзы на прием не-POD-типов?

Ответ 1

Ты в основном по своему усмотрению. Примечание в стандарте объясняет это (9.5/2):

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

Итак, если какой-либо из конструкторов элементов нетривиален, вам нужно написать конструктор для объединения (если все они тривиальны, состояние по умолчанию будет неинициализировано, например, для union { int; double; }). Если у каких-либо членов есть деструктор, вам нужно написать деструктор для объединения, который должен позаботиться о том, чтобы выяснить активный элемент.

Далее следует примечание (9.5/4) о типичном использовании неограниченного объединения:

В общем, нужно использовать явные вызовы деструктора и назначить новые операторы для изменения активного член союза.

Ответ 2

Альтернативы объединению:

std::any/std::variant (С++ 17)

boost::any/boost::variant

Они позволяют использовать типы данных, отличных от POD.