Classes and class hierarchies
C.181
Избегайте «голых» `union`
Причина
Голый union — это union без связанного индикатора того, какой из членов (если вообще какой-то) в нём хранится; программист вынужден отслеживать это самостоятельно. Голые объединения являются источником ошибок типизации.
Пример (плохой)
union Value {
int x;
double d;
};
Value v;
v.d = 987.654; // v хранит double
Пока всё в порядке, но union легко использовать неправильно:
cout << v.x << '\n'; // ПЛОХО: неопределённое поведение: v хранит double, а мы читаем как int
Обратите внимание: ошибка типизации произошла без явного приведения. При тестировании программы последнее выведенное значение было 1683627180 — целочисленное значение битового представления числа 987.654. Перед нами «невидимая» ошибка типизации, дающая результат, который легко принять за корректный.
Кстати, следующий код не вывел ничего:
v.x = 123;
cout << v.d << '\n'; // ПЛОХО: неопределённое поведение
Альтернатива
Оберните union в класс вместе с полем-тегом типа.
Тип variant из C++17 (заголовок <variant>) делает это за вас:
variant<int, double> v;
v = 123; // v хранит int
int x = get<int>(v);
v = 123.456; // v хранит double
double w = get<double>(v);
Контроль
???