0
0
CppHow-ToBeginner · 3 min read

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::get for 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

FeatureDescription
std::variantType-safe union holding one of Ts types
std::get(v)Access value if variant holds type T, else throws
std::holds_alternative(v)Check if variant currently holds type T
std::visit(visitor, v)Call visitor with the current value of variant
Assigning valueAssign 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.