静态多维数组,在编译时定义维度

时间:2019-07-19 20:38:27

标签: c++ arrays c++17 compile-time

是否有任何语法可以在编译时定义静态数组的维数?假设我有一个大小为D的元组,值为d_0,...,d_{D-1}。我希望能够创建一个数组T arr[d_0][d_1]...[d_{D-1}]。有什么办法可以在编译时实现?我专门问的是静态数组语法,而不是关于如何嵌套结构。

下面是一个代码片段,用以阐明我要实现的目标:

template<typename T, template<typename, auto> typename Container, auto DimC, auto...Dim>
struct NestedContainer
{
    using type = Container<typename NestedContainer<T, Container, Dim...>::type, DimC>;
};

template<typename T, template<typename, auto> typename Container, auto Dim>
struct NestedContainer<T, Container, Dim>
{
    using type = Container<T, Dim>;
};

template<typename T, int D>
struct Arr
{
    T e[D];

    T& operator[](int i) { return e[i]; }
};

template<typename T, int D, int...Dim>
struct MultiArr
{
    using multi_arr = typename NestedContainer<T, Arr, Dim...>::type;
    multi_arr e[D];

    auto& operator[](int i) { return e[i]; }
};

使用方式如下:

MultiArr<float, 3, 3, 3> a;
a[2][2][2] = 3;

我很好奇这是否可以通过某种形式的语法而无需嵌套类来实现。

1 个答案:

答案 0 :(得分:6)

使用模板元编程递归可以轻松完成。唯一棘手的事情是,您需要以正确的顺序应用范围。请注意,int[x][y]在概念上是(int[y])[x]

#include <cstddef>
#include <type_traits>

template <typename E, size_t... extents>
struct MultiArrHelper;

template <typename E>
struct MultiArrHelper<E> {
    using type = E;
};

template <typename E, size_t extent, size_t... extents>
struct MultiArrHelper<E, extent, extents...> {
    using type = typename MultiArrHelper<E, extents...>::type[extent];
};

template <typename E, size_t... extents>
using MultiArr = typename MultiArrHelper<E, extents...>::type;

int main() {
    MultiArr<int, 2, 2, 3> a;
    static_assert(std::is_same<decltype(a), int[2][2][3]>::value);
}

http://coliru.stacked-crooked.com/a/6b89020318e78b90