std::variant
(C++)
The class template std::variant
represents a type-safe union.
Resources
It’s a great alternative to using std::union and std::any because it provides better type safety and ease of use.
#include <variant>
std::variant<int, float, std::string> myVariant;
myVariant = 10;
// Access the value using std::get
std::cout << "The value is: " << std::get<int>(myVariant) << "\n";
// Assign a string value to the variant
myVariant = std::string("Hello, variant!");
// Access the string value
std::cout << "The value is: " << std::get<std::string>(myVariant) << "\n";
// Handling exceptions: try to access the wrong type
try {
std::cout << "Attempting to access an int: " << std::get<int>(myVariant) << "\n";
} catch (const std::bad_variant_access& e) {
std::cout << "Exception: " << e.what() << "\n";
}
Saw this in CS343.
An example that they gave:
enum Alloc { NoStorage };
variant<int *, Alloc> Malloc(size_t size) {
if (random() % 2) return (int *)malloc(sizeof(int));
return NoStorage;
}
enum Comp { BadComp };
variant<int, Alloc, Comp> rtn() {
variant<int *, Alloc> p = Malloc(sizeof(int));
if (!holds_alternative<int *>(p)) return NoStorage; // malloc successful ?
*get<int *>(p) = 7;
if (random() % 2) return *get<int *>(p);
return BadComp;
}
int main() {
srandom(getpid());
variant<int, Alloc, Comp> ret = rtn();
if (holds_alternative<int>(ret))
cout << get<int>(ret) << endl;
else if (holds_alternative<Comp>(ret))
cout << "bad computation" << endl;
else
cout << "no storage" << endl;
}