How to Use std::variant in C++: Syntax and Examples
Use
std::variant to store one value from multiple types safely in C++. Define it with the types you want, assign a value, and access it using std::get or std::visit.Syntax
std::variant is a type-safe union that can hold one value from a set of specified types. You declare it by listing the types inside angle brackets. You can assign a value of any of those types to the variant. To access the stored value, use std::get<Type>(variant) or std::visit with a visitor function.
- std::variant<T1, T2, ...>: holds one of the types T1, T2, etc.
- std::get<T>(v): gets the value if it holds type T, else throws
std::bad_variant_access. - std::visit(visitor, v): calls visitor with the currently held value.
cpp
std::variant<int, float, std::string> v; v = 42; // holds int v = 3.14f; // holds float v = "hello"; // holds std::string int i = std::get<int>(v); // throws if v does not hold int std::visit([](auto&& arg){ std::cout << arg; }, v);
Example
This example shows how to create a std::variant that can hold an int, float, or std::string. It assigns different types and uses std::visit to print the current value.
cpp
#include <iostream> #include <variant> #include <string> int main() { std::variant<int, float, std::string> v; v = 10; std::visit([](auto&& arg){ std::cout << "Value: " << arg << '\n'; }, v); v = 5.5f; std::visit([](auto&& arg){ std::cout << "Value: " << arg << '\n'; }, v); v = std::string("hello"); std::visit([](auto&& arg){ std::cout << "Value: " << arg << '\n'; }, v); return 0; }
Output
Value: 10
Value: 5.5
Value: hello
Common Pitfalls
Common mistakes when using std::variant include:
- Trying to get a value with
std::getfor a type the variant does not currently hold, which throws an exception. - Not handling all possible types when using
std::visit, which can cause unexpected behavior. - Assigning a type not listed in the variant's template parameters, which causes a compile error.
Always check the active type with std::holds_alternative<T>(v) before using std::get<T>(v) to avoid exceptions.
cpp
/* Wrong way: throws if variant does not hold int */ // int x = std::get<int>(v); /* Right way: check before getting */ // if (std::holds_alternative<int>(v)) { // int x = std::get<int>(v); // }
Quick Reference
| Feature | Description |
|---|---|
| std::variant | Type-safe union holding one of Ts types |
| std::get | Access value if variant holds type T, else throws |
| std::holds_alternative | Check if variant currently holds type T |
| std::visit(visitor, v) | Call visitor with the current value of variant |
| Assigning value | Assign a value of any type listed in variant |
Key Takeaways
std::variant holds one value from multiple specified types safely.
Use std::get or std::visit to access the stored value.
Always check the active type with std::holds_alternative before std::get to avoid exceptions.
std::visit is a clean way to handle all possible types with a visitor function.
Assign only types declared in the variant template; others cause compile errors.