Search code examples
c++templatesc++14

Expand template type


Is there a way to convert each type of std::tuple into specific subtypes? I have following code

struct Foo1
{
    struct A{};
    struct B{};
};

struct Foo2
{
    struct A{};
    struct B{};
};

using myTypes = std::tuple<Foo1, Foo2>;

Is there a way to convert myTypes into following type?

std::tuple<Foo1::A, Foo1::B, Foo2::A, Foo2::B>;

Order of types doesn't matter, but would be nice to have it like above.


Solution

  • If A/B name are fixed, you might do

    template <typename... Ts>
    using AB_Types = std::tuple<typename Ts::A..., typename Ts::B...>;
    

    So AB_Types<Foo1, Foo2> is std::tuple<Foo1::A, Foo2::A, Foo1::B, Foo2::B>.

    Having expected order would also be possible:

    template <typename... Ts>
    using AB_Types_ordered =
        decltype(std::tuple_cat(std::tuple<typename Ts::A, typename Ts::B>{}...));
    

    and if source is a tuple, just add extra layer

    template <typename>
    struct AB_impl;
    
    template <typename... Ts>
    struct AB_impl<std::tuple<Ts...>>
    {
        using type = AB_Types<Ts...>; // AB_Types_ordered<Ts...>
    };
    
    template <typename T>
    using AB_Types_from_tuple = typename AB_impl<T>::type;