How to access items inside nested structs that contain a modern tagged union in C++

1 Answer

0 votes
#include <iostream>
#include <string>
#include <variant>
#include <type_traits>

// 1. Define specific component structs
struct Circle {
    float radius;
};

struct Rectangle {
    float width;
    float height;
};

// 2. Define metadata structure using std::string instead of raw char arrays
struct Metadata {
    std::string name;
    bool is_active;
};

// 3. Define the main container struct using std::variant for type-safe variants
struct Shape {
    int id;
    Metadata metadata;
    
    // std::variant handles the type tagging and safety automatically
    std::variant<Circle, Rectangle> dimensions;
};

/**
 * @brief Safely inspects shape properties using std::visit (compile-time pattern matching).
 * @param shape Reference to the Shape object.
 */
void print_shape_properties(const Shape& shape) {
    std::cout << "Shape ID: " << shape.id << "\n";
    std::cout << "Shape Name: " << shape.metadata.name << "\n";
    std::cout << "Status: " << (shape.metadata.is_active ? "Active" : "Inactive") << "\n";

    // std::visit inspects whichever type is currently active in the variant
    std::visit([](const auto& dim) {
        using T = std::decay_t<decltype(dim)>;
        if constexpr (std::is_same_v<T, Circle>) {
            std::cout << "Type: Circle\n";
            std::cout << "Radius: " << dim.radius << "\n";
        } else if constexpr (std::is_same_v<T, Rectangle>) {
            std::cout << "Type: Rectangle\n";
            std::cout << "Width: " << dim.width << ", Height: " << dim.height << "\n";
        }
    }, shape.dimensions);

    std::cout << "------------------------------------\n";
}

int main() {
    // Modern design initializer lists
    Shape my_circle{
        .id = 101,
        .metadata = {.name = "Unit Circle", .is_active = true},
        .dimensions = Circle{5.5f}
    };

    Shape my_rectangle{
        .id = 102,
        .metadata = {.name = "Bounding Box", .is_active = false},
        .dimensions = Rectangle{10.0f, 20.0f}
    };

    print_shape_properties(my_circle);
    print_shape_properties(my_rectangle);
}


/*
run:

Shape ID: 101
Shape Name: Unit Circle
Status: Active
Type: Circle
Radius: 5.5
------------------------------------
Shape ID: 102
Shape Name: Bounding Box
Status: Inactive
Type: Rectangle
Width: 10, Height: 20
------------------------------------

*/

 



answered 11 hours ago by avibootz

Related questions

...