简体   繁体   中英

constexpr to return tuple of dimensions of a multidimensional C-style array

Is there a way to extend/modify/implement a constexpr to return a std::tuple of the dimensions of a multidimensional C-style array?

#include <iostream>
#include <tuple>
template<typename T, std::size_t N>
auto arraysize(T (&arr)[N])
{
    return std::make_tuple(N);
}

IOW, how to make arraysize to work for any-dimensional array? The above "works" but only returns one dimension:

int i[5];
std::cout << std::get<0>(arraysize(i)) << std::endl;

works, and returns 5. And,

char c[3][4];
std::cout << std::get<0>(arraysize(c)) << std::endl;

works, and returns 3, but

std::cout << std::get<1>(arraysize(c)) << std::endl;

doesn't compile because the arraysize() is not coded right. Is there a way to code it as a constexpr to handle any-dimensional array? Tried using parameter packs but was not successful.

Use std::rank and std::extent with the index sequence trick: live example

#include <tuple>
#include <type_traits>
#include <utility>

template<typename Arr, std::size_t... Is>
constexpr auto extents_impl(const Arr&, std::index_sequence<Is...>) {
    return std::make_tuple(std::extent_v<Arr, Is>...);
}

template<typename Arr>
constexpr auto extents(const Arr& arr) {
    return extents_impl(arr, std::make_index_sequence<std::rank_v<Arr>>{});
}

These traits also return 0 for a non-array type or an array of unknown bound, leaving you with an empty tuple if your function is not given an array type. You can, of course, perform additional checking there if you wish.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM