Search code examples
c++c++20variant

Is it possible to group structs for use with std::variant


I'm designing a class to represent data from 10+ sources using std::variant. Each source may have 10 different messages, so the variant will represent 100 different underlying structs.

Understandably I'd like to declare the std::variant without listing 100 types in the declaration:

std::variant<Type1, Type2, Type3............................ Type100>

I'd prefer to sub-group the 10 structs per 'source' and the variant consist of the groups:

std::variant<Source1Types, Source2Types.... Source10Types>

Is there a way to sub-group structs, for use with std::variant? If not, is there any other way of achieving this?

(I'm using C++20)


Solution

  • You might do:

    using Source0Types = std::variant<Type0, Type1, Type2, Type3, .., Type9>;
    using Source1Types = std::variant<Type10, Type11, Type12, Type13, .., Type19>;
    // ..
    
    using SourceTypeVariant = std::variant<Source0Types, Source1Types, .., Source9Types>;
    

    The caveat here is that you have two levels of variant (for the visit).

    You might create trait to flatten/concatenate the variants:

    template <typename ... Vs> struct concatenate;
    template <typename ... Vs> using concatenate_t = typename concatenate<Vs...>::type;
    
    template <typename ... Ts> struct concatenate<std::variant<Ts...>>
    {
        using type = std::variant<Ts...>;
    };
    
    template <typename ... Ts, typename ... Us, typename ... Vs>
    struct concatenate<std::variant<Ts...>, std::variant<Us...>, Vs...> :
        concatenate<std::variant<Ts..., Us...>, Vs...>
    {
    };
    

    And so

    using MegaVariant = concatenate_t<Source0Types, Source1Types, .., Source9Types>;