Where to use std::variant over union?
Please explain what is the difference between union
and std::variant
and why std::variant
was introduced into the standard? In what situations should we use std::variant
over the old-school union
?
Generally speaking, you should prefer variant
unless one of the following comes up:
-
You're cheating. You're doing type-punning or other things that are UB but you're hoping your compiler won't break your code.
-
You're doing some of the pseudo-punnery that C++
union
s are allowed to do: conversion between layout-compatible types or between common initial sequences. -
You explicitly need layout compatibility.
variant<Ts>
are not required to have any particular layout;unions
of standard layout types are standard layout. -
You need low-level support for in-place switching of objects. Using a memory buffer for such things doesn't provide the trivial copying guarantees that you could get out of a
union
.
The basic difference between the two is that variant
knows which type it stores, while union
expects you to keep track of that externally. So if you try to access the wrong item in a variant
, you get an exception or nullptr
. By contrast, doing so with a union
is merely undefined behavior.
union
is a lower-level tool, and thus should only be used when you absolutely need that lower-level.
variant
also has machinery for doing visitation, which means you get to avoid having a bunch of if
statements where you ask "if it is type X, do this. If it is type Y, do that, etc".