std::variant — type-safe union. std::visit — apply function to variant.
1#include <variant>23std::variant<int, double, std::string> v;45// Visit with overloaded lambda (C++17)6std::visit([](auto&& arg) {7 using T = std::decay_t<decltype(arg)>;8 if constexpr (std::is_same_v<T, int>) {9 std::cout << "int: " << arg;10 } else if constexpr (std::is_same_v<T, double>) {11 std::cout << "double: " << arg;12 } else {13 std::cout << "string: " << arg;14 }15}, v);1617// Overloaded pattern (C++17)18template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };19template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;2021std::visit(overloaded{22 [](int i) { std::cout << i; },23 [](double d) { std::cout << d; },24 [](const std::string& s) { std::cout << s; }25}, v);2627// Visit multiple variants28std::variant<int, double> v1 = 1;29std::variant<int, std::string> v2 = "hello";3031std::visit([](auto&& a, auto&& b) {32 std::cout << a << ", " << b;33}, v1, v2);3435// Index36std::cout << v.index(); // Current type index3738// Get39if (auto* p = std::get_if<int>(&v)) {40 std::cout << *p;41}
Key insight: visit + overloaded pattern enables pattern matching.