Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to use std::variant over union?

Tags:

c++

c++17

People also ask

What is std :: variant in C++?

The class template std::variant represents a type-safe union. An instance of std::variant at any given time either holds a value of one of its alternative types, or in the case of error - no value (this state is hard to achieve, see valueless_by_exception).

Does std :: variant allocate?

According to cppreference ::std::variant must not allocate dynamic memory.

How does STD variant work?

std::variant (C++17)An instance of std::variant has a value from one of its types. The value must not be a reference, C-array or void. A std::variant can have one type more than once. A default-initialized std::variant will be initialized with its first type.

Does STD variant require RTTI?

Since this function is specific to a given type, you don't need RTTI to perform the operations required by std::any .


Generally speaking, you should prefer variant unless one of the following comes up:

  1. 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.

  2. You're doing some of the pseudo-punnery that C++ unions are allowed to do: conversion between layout-compatible types or between common initial sequences.

  3. You explicitly need layout compatibility. variant<Ts> are not required to have any particular layout; unions of standard layout types are standard layout.

  4. 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".