Search code examples
c++stdarray

Getting root type of multidimensional variadic std::array


I have nested std::array which dimension is handled by template arguments std::array<type, n, ...>.

I was wondering how to get for example in std::array<std::array<int, 2>, 2>, the type int.

in this case we could just do std::array<std::array<int, 2>, 2>::value_type::value_type, but how can I do this without having to put as many value_types as there are dimensions?


Solution

  • You can use a basic recursive technique:

    template <typename T>
    struct nested_value_type { using type = T; };
    
    template <typename T, std::size_t N>
    struct nested_value_type<std::array<T, N>>
    {
        using type = typename nested_value_type<T>::type;
    };
    

    Provide an alias template for convenience:

    template <typename T>
    using nested_value_type_t = typename nested_value_type<T>::type;
    

    And voila:

    static_assert(std::is_same_v<
        nested_value_type_t<std::array<int, 1>>,
        int
    >);
    
    static_assert(std::is_same_v<
        nested_value_type_t<std::array<std::array<float, 1>, 1>>,
        float
    >);
    
    static_assert(std::is_same_v<
        nested_value_type_t<std::array<std::array<std::array<char, 1>, 1>, 1>>,
        char
    >);
    

    live example on godbolt.org


    A bit shorter with C++20's std::type_identity:

    template <typename T>
    struct nested_value_type : std::type_identity<T> { };
    
    template <typename T>
    using nested_value_type_t = typename nested_value_type<T>::type;
    
    template <typename T, std::size_t N>
    struct nested_value_type<std::array<T, N>> 
        : std::type_identity<nested_value_type_t<T>> { };