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;
}