Variant
In C++, std::variant is a type-safe, generic container that can hold one value out of a set of specified types. It was introduced in C++17 as part of the Standard Library and is defined in the <variant> header. std::variant can be thought of as a type-safe union that allows you to store different types of values but only one type at a time.
Key Features of std::variant
std::variantType-Safety: Unlike traditional unions,
std::variantis type-safe, meaning it keeps track of the type of the value currently stored in it and ensures that only valid operations are performed.Multiple Types:
std::variantcan hold any one of the types specified in its template parameters. For example,std::variant<int, float, std::string>can hold either anint, afloat, or astd::string.Visitors and
std::visit: To safely retrieve and work with the value stored in astd::variant, you can usestd::visitalong with a visitor function or lambda.Exceptions: If you attempt to retrieve a value of a type that is not currently stored in the variant, an exception (
std::bad_variant_access) will be thrown.
Basic Usage of std::variant
std::variant1. Including the Header
To use std::variant, you need to include the <variant> header:
cppCopy code#include <variant>2. Declaring a std::variant
You can declare a std::variant that can hold any one of several types:
cppCopy codestd::variant<int, float, std::string> v;This variant v can hold an int, a float, or a std::string, but only one of them at any given time.
3. Assigning a Value
You can assign a value of any of the specified types to the std::variant:
cppCopy codev = 42; // v now holds an int
v = 3.14f; // v now holds a float
v = "Hello"; // v now holds a std::string4. Accessing the Value
To access the value stored in a std::variant, you can use std::get:
If the variant does not currently hold the requested type, std::get throws std::bad_variant_access:
5. Checking the Active Type
You can check which type is currently held by the std::variant using std::holds_alternative:
Alternatively, you can use std::visit to apply a visitor function or lambda to the currently held value:
Example: Using std::variant
std::variantHere’s an example that demonstrates how to use std::variant:
Output:
Explanation:
Variant Declaration:
std::variant<int, float, std::string> v;declares a variantvthat can hold either anint, afloat, or astd::string.
Assigning Values:
v = 42;assigns aninttov.v = 3.14f;assigns afloattov.v = "Hello, World!";assigns astd::stringtov.
Using
std::visit:std::visit(PrintVisitor{}, v);applies thePrintVisitorto the value currently held byv, printing it according to its type.
Advanced Features of std::variant
std::variant1. Default Value and Alternative Index
You can specify which alternative is the default using std::variant_alternative:
You can also retrieve the index of the currently held type:
2. Monostate
If you want to include an "empty" state in your variant, you can use std::monostate:
When to Use std::variant
std::variantPolymorphism: When you need a type-safe way to hold one of several types in a single variable, and you don't want to use inheritance or pointers.
Function Return Types: When a function can return different types based on conditions.
Union Replacement: When you need the flexibility of a union but with type safety.
Conclusion
std::variant in C++ provides a powerful, type-safe alternative to traditional unions, allowing you to store and manipulate one value from a set of types. With std::variant, you can safely handle different types in a single variable and make your code more robust and easier to maintain. It is particularly useful in situations where a variable can hold one of several types and when you want to ensure type safety and avoid errors related to manual type management.
Last updated