# variant

***

**1. Store Different Data Types in a Single Container**

```cpp
#include <variant>

struct Point { double x, y; };
using Circle = std::variant<Point, double>;

int main() {
    Circle c1 = Point{1.0, 2.0};
    Circle c2 = 10.0;
}
```

**2. Handle Null Pointers**

```cpp
#include <variant>

using OptionalInt = std::optional<int>;

int main() {
    OptionalInt oi; // Initialized as null
    oi = 10; // Set a value
    if (oi) {
        // Handle the value
    } else {
        // Handle null
    }
}
```

**3. Represent a Union of Classes**

```cpp
#include <variant>

class Shape { virtual ~Shape() = default; };
class Circle : public Shape { ... };
class Rectangle : public Shape { ... };

using ShapeVariant = std::variant<Circle, Rectangle>;

int main() {
    ShapeVariant s = Circle();
    if (std::holds_alternative<Circle>(s)) {
        // Handle Circle
    } else if (std::holds_alternative<Rectangle>(s)) {
        // Handle Rectangle
    }
}
```

**4. Reduce Branching**

```cpp
#include <variant>

using Request = std::variant<int, std::string>;

int main() {
    Request req = 10;
    switch (req.index()) {
        case 0: // Integer value
            // Handle integer
            break;
        case 1: // String value
            // Handle string
            break;
    }
}
```

**5. Implement Type Erasure**

```cpp
#include <variant>

struct Animal { virtual ~Animal() = default; };
struct Cat : public Animal { ... };
struct Dog : public Animal { ... };

using AnimalVariant = std::variant<Cat, Dog>;

int main() {
    AnimalVariant animal = Cat();
    animal.visit([](auto& a) { a.makeSound(); }); // Visit the held object
}
```

**6. Store a Set of Values**

```cpp
#include <variant>

using ValueSet = std::variant<int, double, std::string>;

int main() {
    ValueSet values = 10;
    std::visit([](auto& v) { std::cout << v << '\n'; }, values); // Print each value
}
```

**7. Implement an Enum with Associated Data**

```cpp
#include <variant>

enum class Color {
    Red,
    Green,
    Blue
};

using ColorWithHex = std::variant<Color, std::string>;

int main() {
    ColorWithHex c = Color::Red;
    // Get the hex value using std::get<std::string>(c)
}
```

**8. Store a Range of Values**

```cpp
#include <variant>

using Range = std::variant<int, std::pair<int, int>>;

int main() {
    Range r = 10;
    std::visit([](auto& v) { // v can be int or std::pair<int, int>
        if constexpr (std::is_same_v<std::decay_t<decltype(v)>, int>) {
            // Handle single value
        } else {
            // Handle range
        }
    }, r);
}
```

**9. Represent a Heterogeneous Collection**

```cpp
#include <variant>

using Collection = std::variant<int, double, bool, std::string>;

int main() {
    Collection c = false;
    std::visit([](auto& v) { std::cout << typeid(v).name() << '\n'; }, c); // Print type name
}
```

**10. Detect Type at Runtime**

```cpp
#include <variant>

using Value = std::variant<int, double, char>;

int main() {
    Value v = 10;
    if (std::holds_alternative<int>(v)) {
        // Handle int
    }
}
```

**11. Combine Variants**

```cpp
#include <variant>

using A = std::variant<int, double>;
using B = std::variant<std::string, bool>;

using AB = std::variant<A, B>;

int main() {
    AB ab = A(10);
    if (std::holds_alternative<A>(ab)) {
        // Handle A
    } else if (std::holds_alternative<B>(ab)) {
        // Handle B
    }
}
```

**12. Check for Null Values**

```cpp
#include <variant>

using OptionalInt = std::optional<int>;

int main() {
    OptionalInt oi;
    if (!oi) {
        // Handle null
    }
}
```

**13. Extract Values**

```cpp
#include <variant>

using Value = std::variant<int, double, bool>;

int main() {
    Value v = 10;
    int i = std::get<0>(v); // Extract int value
}
```

**14. Iterate Over Variants**

```cpp
#include <variant>
#include <algorithm>

using Value = std::variant<int, double, bool>;

int main() {
    Value v;
    std::for_each(v.begin(), v.end(), [](auto& val) { std::cout << val << '\n'; });
}
```

**15. Create Variadic Variants**

```cpp
#include <variant>

using Value = std::variant<std::monostate, int, double, std::string>;

int main() {
    Value v = 10;
}
```

**16. Compare Variants**

```cpp
#include <variant>

using A = std::variant<int, double>;
using B = std::variant<int, double>;

int main() {
    A a = 10;
    B b = 10.0;
    if (a == b) {
        // Equal
    }
}
```

**17. Store a Pointer to an Object**

```cpp
#include <variant>

struct Shape { virtual ~Shape() = default; };
class Circle : public Shape { ... };

using ShapePtr = std::variant<std::monostate, std::unique_ptr<Shape>>;

int main() {
    ShapePtr sp = std::make_unique<Circle>();
}
```

**18. Implement a Polymorphic Function**

```cpp
#include <variant>

struct Shape { virtual ~Shape() = default; };
struct Circle : public Shape { ... };
struct Rectangle : public Shape { ... };

using ShapeVariant = std::variant<Circle, Rectangle>;

void draw(ShapeVariant& shape) {
    std::visit([](auto& s) { s.draw(); }, shape);
}
```

**19. Handle Unknown Types**

```cpp
#include <variant>

struct Shape { virtual ~Shape() = default; };
class Circle : public Shape { ... };
class Rectangle : public Shape { ... };

using ShapeVariant = std::variant<Circle, Rectangle, std::monostate>;

void draw(ShapeVariant& shape) {
    if (std::holds_alternative<std::monostate>(shape)) {
        // Handle unknown type
    } else {
        std::visit([](auto& s) { s.draw(); }, shape);
    }
}
```

**20. Store a Function**

```cpp
#include <variant>

int add(int a, int b) { return a + b; }

using Function = std::variant<std::monostate, int(*)(int, int)>;

int main() {
    Function f = add;
    int result = std::get<1>(f)(10, 15); // Invoke the stored function
}
```

**21. Implement a Customizable Data Structure**

```cpp
#include <variant>

template<typename... Ts>
struct DataStructure {
    std::variant<Ts...> data;
};

// Usage:
using MyDataStructure = DataStructure<int, double, std::string>;
```

**22. Represent a JSON Object**

```cpp
#include <variant>

using JSONValue = std::variant<int, double, std::string, bool, std::vector<JSONValue>, std::map<std::string, JSONValue>>;

JSONValue parseJSON(const std::string& json) {
    // Parse the JSON string and return a variant representing the parsed object
}
```

**23. Represent a Binary Tree**

```cpp
#include <variant>

struct TreeNode {
    int value;
    std::variant<TreeNode*, std::monostate> left, right;
};
```

**24. Implement a Type-Safe Union**

```cpp
#include <variant>

template<typename... Ts>
struct Union {
    std::variant<Ts...> value;
    template<typename T>
    T& get() { return std::get<T>(value); }
};
```

**25. Represent a Finite State Machine**

```cpp
#include <variant>

enum class State { START, IDLE, PROCESSING, COMPLETED };

using FSM = std::variant<State, std::pair<State, int>>;

// Transition function
FSM transition(FSM& fsm, int input) {
    // ...
}
```

**26. Store a Lazy-Evaluated Value**

```cpp
#include <variant>

using Lazy = std::variant<int, std::function<int()>>;

Lazy fib(int n) {
    if (n <= 1) {
        return n;
    } else {
        return [n] {
            return std::get<1>(fib(n - 1)) + std::get<1>(fib(n - 2));
        };
    }
}
```

**27. Implement a Variant-Based Queue**

```cpp
#include <variant>

struct QueueItem {
    std::variant<std::monostate, int, double, std::string> data;
    std::unique_ptr<QueueItem> next;
};
```

**28. Represent a Variant of Containers**

```cpp
#include <variant>

using Container = std::variant<std::vector<int>, std::list<double>, std::map<std::string, std::string>>;
```

**29. Implement a Visitor Pattern**

```cpp
#include <variant>
#include <iostream>

struct Shape { virtual ~Shape() = default; };
struct Circle : public Shape { void draw() { std::cout << "Circle" << '\n'; } };
struct Rectangle : public Shape { void draw() { std::cout << "Rectangle" << '\n'; } };

using ShapeVariant = std::variant<Circle, Rectangle>;

struct ShapeVisitor {
    void operator()(const Circle&) { std::cout << "Drawing Circle\n"; }
    void operator()(const Rectangle&) { std::cout << "Drawing Rectangle\n"; }
};

void drawShape(const ShapeVariant& shape) {
    std::visit(ShapeVisitor(), shape);
}
```

**30. Represent a Function with Multiple Signatures**

```cpp
#include <variant>

using Function = std::variant<std::function<int(int)>, std::function<double(double, double)>, std::function<std::string(std::string, std::string)>>;
```

**31. Store a Polymorphic Reference**

```cpp
#include <variant>

struct Base { virtual ~Base() = default; };
struct Derived1 : public Base { ... };
struct Derived2 : public Base { ... };

using BasePtr = std::variant<std::unique_ptr<Base>, std::unique_ptr<Derived1>, std::unique_ptr<Derived2>>;
```

**32. Implement a Type-Erased Class**

```cpp
#include <variant>

struct TypeErased {
    std::variant<int, double, std::string> data;
};
```

**33. Store a Range of Values with Step**

```cpp
#include <variant>

using RangeWithStep = std::variant<int, std::pair<int, int>, std::tuple<int, int, int>>;
```

**34. Represent a Sparse Array**

```cpp
#include <variant>

struct SparseArray {
    std::variant<std::monostate, std::pair<size_t, int>> data;
    // ...
};
```

**35. Implement a Type-Safe Union with Default Value**

```cpp
#include <variant>
#include <type_traits>

template<typename... Ts>
struct UnionWithDefaultValue {
    std::variant<Ts...> value;
    constexpr UnionWithDefaultValue() : value(std::in_place_type<std::decay_t<Ts>>()) {}
    // ...
};
```

**36. Store a Function with Bound Arguments**

```cpp
#include <variant>

using BoundFunction = std::variant<std::monostate, std::function<int(int, int)>, std::function<double(int, double)>>;
```

**37. Implement a Type-Erased Tuple**

```cpp
#include <variant>

template<typename... Ts>
struct TupleErased {
    std::variant<std::monostate, Ts...> data;
};
```

**38. Represent a Union of References**

```cpp
#include <variant>

struct Base { virtual ~Base() = default; };
struct Derived1 : public Base { ... };
struct Derived2 : public Base { ... };

using BaseRef = std::variant<std::reference_wrapper<Base>, std::reference_wrapper<Derived1>, std::reference_wrapper<Derived2>>;
```

**39. Store a Variant of Optionals**

```cpp
#include <variant>

using VariantOptional = std::variant<std::monostate, std::optional<int>, std::optional<double>, std::optional<std::string>>;
```

**40. Implement a Type-Safe Union with Default Construction**

```cpp
#include <variant>

template<typename... Ts>
struct UnionWithDefaultConstruction {
    std::variant<Ts...> value;
    UnionWithDefaultConstruction() = default;
    // ...
};
```

**41. Represent a Union of Unique Pointers**

```cpp
#include <variant>

struct Base { virtual ~Base() = default; };
struct Derived1 : public Base { ... };
struct Derived2 : public Base { ... };

using BasePtr = std::variant<std::unique_ptr<Base>, std::unique_ptr<Derived1>, std::unique_ptr<Derived2>>;
```

**42. Store a Variant of Pairs**

```cpp
#include <variant>

using PairVariant = std::variant<std::pair<int, int>, std::pair<double, double>, std::pair<std::string, std::string>>;
```

**43. Implement a Type-Safe Union with Custom Construction**

```cpp
#include <variant>

template<typename... Ts>
struct UnionWithCustomConstruction {
    std::variant<Ts...> value;
    UnionWithCustomConstruction(const Ts&... args) : value(std::in_place_type<Ts>, args...) {}
    // ...
};
```

**44. Represent a Union of Weak Pointers**

```cpp
#include <variant>

struct Base { virtual ~Base() = default; };
struct Derived1 : public Base { ... };
struct Derived2 : public Base { ... };

using BaseWeakPtr = std::variant<std::weak_ptr<Base>, std::weak_ptr<Derived1>, std::weak_ptr<Derived2>>;
```

**45. Store a Variant of Arrays**

```cpp
#include <variant>

using ArrayVariant = std::variant<int[3], double[5], std::string[10]>;
```

**46. Implement a Type-Safe Union with Multiple Default Values**

```cpp
#include <variant>

template<typename... Ts>
struct UnionWithMultipleDefaultValues {
    std::variant<Ts...> value;
    constexpr UnionWithMultipleDefaultValues()
        : value(std::in_place_type<std::decay_t<Ts>>(), std::decay_t<Ts>::default_value()) {}
    // ...
};
```

**47. Represent a Union of Shared Pointers**

```cpp
#include <variant>

struct Base { virtual ~Base() = default; };
struct Derived1 : public Base { ... };
struct Derived2 : public Base { ... };

using BaseSharedPtr = std::variant<std::shared_ptr<Base>, std::shared_ptr<Derived1>, std::shared_ptr<Derived2>>;
```

**48. Store a Variant of Structs**

```cpp
#include <variant>

struct Point { int x, y; };
struct Circle { double radius; };

using ShapeVariant = std::variant<Point, Circle>;
```

**49. Implement a Type-Safe Union with Default Value and Custom Construction**

```cpp
#include <variant>

template<typename... Ts>
struct UnionWithDefaultAndCustomConstruction {
    std::variant<Ts...> value;
    constexpr UnionWithDefaultAndCustomConstruction() : value(std::in_place_type<std::decay_t<Ts>>()) {}
    UnionWithDefaultAndCustomConstruction(const Ts&... args) : value(std::in_place_type<Ts>, args...) {}
    // ...
};
```

**50. Represent a Union of Class Instances**

```cpp
#include <variant>

class Base { virtual ~Base() = default; };
class Derived1 : public Base { ... };
class Derived2 : public Base { ... };

using BaseInstance = std::variant<Base, Derived1, Derived2>;
```
