Некоторые ошибки в вашем коде.
(1) использовать постоянно type
или index_type
, но не запрашивать type
// .......................................................................vvvv
typename unpacked_array_type_impl<T,make_index_sequence<rank<T>::value>>::type;
когда класс определяют index_type
template<typename T, size_t...I>
struct unpacked_array_type_impl<T,index_sequence<I...>> {
using index_type = index_sequence<extent<T[I]>::value...>;
}; // ..^^^^^^^^^^
Та же проблема для unpacked_array_sequence
, которая определяет index_type
, когда в main()
вы запрашиваете type
(2) используйте std::extent<T, I>::value...
, а не extent<T[I]>::value...
.
Также обратите внимание, что с помощью extent<T[I]>::value ...
вы определяете T[0]
(когда I
равен нулю), что не приемлемо в стандарте C ++.
(3) добавить template <std::size_t ... N>
до
void print_sequence( const index_sequence<N...>& seq, ostream& os ) {
Исправляя эти ошибки, вы должны получить вывод
[3 4 5 ]
это не совсем то, что вы просили, а улучшение.
Чтобы получить
[0 0 3 4 5 ]
Предлагаю переписать unpacked_array_type_impl
следующим образом
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; };
Ниже приведен полный рабочий пример
#include <utility>
#include <iostream>
#include <type_traits>
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; };
// Print indices for testing
template <std::size_t ... N>
void print_sequence (std::index_sequence<N...> const & seq,
std::ostream & os)
{
using expand_type = int[];
os << "[";
(void) expand_type { 0, ((void)(os << N << " ") , 0) ... };
os << "]\n";
}
int main ()
{
typename unpacked_array_type<double**[3][4][5]>::type x;
print_sequence(x, std::cout); // Desired output = [0 0 3 4 5 ]
}