Search code examples
c++templatesstdmetaprogramming

How can I unpack multidimensional c-style array type and declare std::array instance?


I'm writing a template that can convert a c style multidimensional array to a std array and declare it.

  1. get c-style array matrix
template <typename, typename IS = std::index_sequence<>>
struct unpacked_array_type_impl
{
    using type = IS;
};

template <typename T, std::size_t ... I>
struct unpacked_array_type_impl<T*, std::index_sequence<I...>>
    : public unpacked_array_type_impl<T, std::index_sequence<0u, I...>>
{ };

template <typename T, std::size_t N, std::size_t ... I>
struct unpacked_array_type_impl<T[N], std::index_sequence<I...>>
    : public unpacked_array_type_impl<T, std::index_sequence<I..., N>>
{ };

template<typename T>
struct unpacked_array_type
{
    using type = typename unpacked_array_type_impl<T>::type;
};
  1. std array declaration
template<typename T, size_t size, size_t... more>
struct myArray_impl
{
    using type = std::array<typename myArray_impl<T, more...>::type, size>;
};

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

template<typename T, size_t size, size_t... more>
using myArray = typename myArray_impl<T, size, more...>::type;

Below is the code I want to achieve.

using example_type = int[4][10];
using real_type = std::remove_all_extents<example_type>::type
myArray<real_type, unpacked_array_type<example_type>::type> this_would_be_std_arr;

But I got C2993 error.

The problem is that std::integer_sequence cannot expand to the variable argument of myArray template.

I would appreciate if you can help me.


Solution

  • First template return std::index_sequence, whereas the second take a list of number.

    You might use std::index_sequence for both:

    template<typename T, typename Seq>
    struct myArray_impl;
    
    
    template<typename T, size_t size, size_t... more>
    struct myArray_impl<T, std::index_sequence<size, more...>>
    {
        using type = std::array<typename myArray_impl<T, std::index_sequence<more...>>::type, size>;
    };
    
    template<typename T, size_t size>
    struct myArray_impl<T, std::index_sequence<size>>
    {
        using type = std::array<T, size>;
    };
    
    template<typename T, typename Seq>
    using myArray = typename myArray_impl<T, Seq>::type;
    

    Demo.