用现代C++优雅地定义多维数组

25
使用 T[][][] 语法定义多维数组很容易。然而,这会创建一个原始的数组类型,不适合现代 C++。那么,自 C++11 以来我们有了 std::array。但是,使用 std::array 定义多维数组的语法非常混乱。例如,要定义一个三维的 int 数组,您需要写 std::array<std::array<std::array<int, 5>, 5>, 5>。该语法根本不可扩展。我正在寻求解决此问题的方法。也许,使用 C++ 提供的现有实用工具无法解决此问题。在这种情况下,我希望开发一种自定义工具来简化语法。

我自己找到了一个解决方案

template <typename T, std::size_t n, std::size_t... ns>
struct multi_array {
  using type = std::array<typename multi_array<T, ns...>::type, n>;
};

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

template <typename T, std::size_t... ns>
using multi_array_t = typename multi_array<T, ns...>::type;

想知道这个实现是否可以进一步简化。


3
您可以使用stackoverflow上这个问题的答案中的方法:https://dev59.com/qWAf5IYBdhLWcg3wnDsI,来解决您的问题。 - R Sahu
2
还有https://dev59.com/k2sz5IYBdhLWcg3wv6ju - 同样的问题,但标记为 c++11. - ildjarn
2
请注意,在嵌套的 std::array 中,内存布局不能保证与 C 风格的数组相同(至少在 C++11 中如此,我不确定在 C++14 中是否已解决此问题)。 - juanchopanza
@juanchopanza std::array不就是一个简单的原始数组包装器吗? - Lingxi
1
@Lingxi 但是标准允许在结尾处留有一些填充(至少在C++11中是这样的)。 - juanchopanza
显示剩余6条评论
1个回答

12

请参考C++11中的多维数组


template <class T, std::size_t I, std::size_t... J>
struct MultiDimArray 
{
  using Nested = typename MultiDimArray<T, J...>::type;
  // typedef typename MultiDimArray<T, J...>::type Nested;
  using type = std::array<Nested, I>;
  // typedef std::array<Nested, I> type;
};

template <class T, std::size_t I>
struct MultiDimArray<T, I> 
{
  using type = std::array<T, I>;
  // typedef std::array<T, I> type;
};

MultiDimArray<float, 3, 4, 5, 6, 7>::type floats;

MultiDimArray是一对元函数,用于计算多维std::array的嵌套类型。最通用的MultiDimArray是一个可变参数模板,用于传递任意数量的维度的无符号整数。终止的MultiDimArray特化定义了单维std::array的最简单情况。


这个实现能进一步简化吗? - Lingxi
1
通过在其顶部使用模板别名,可以稍微改进它的使用方式:template using MultiDimArray_t = typename MultiDimArray::type; MultiDimArray_t floatArr; - Mandeep Singh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接