【问题标题】:Loop through unknown number of dimensions循环遍历未知数量的维度
【发布时间】:2019-08-03 17:58:51
【问题描述】:

我想写一个循环,它可以给我一个数组的维度。我想让它可用于任何数组,它应该返回维度的大小。

int arr[3][5][10][9] ;
cout << "dimension 1: " << sizeof(arr)/sizeof(arr[0]) << endl; 
cout << "dimension 2: " << sizeof(arr[0])/sizeof(arr[0][0]) << endl; 
cout << "dimension 3: " << sizeof(arr[0][0])/sizeof(arr[0][0][0]) << endl;
cout << "dimension 4: " << sizeof(arr[0][0][0])/sizeof(arr[0][0][0][0]) << endl;
cout << "dimension 5: " << sizeof(arr[0][0][0][0])/sizeof(arr[0][0][0][0][0]) << endl;

这应该返回3,5,10,9(最后一条语句失败)。

所以模式看起来很清楚“每次迭代在arr 之后添加[0]。最后一次迭代将失败,这应该停止while 循环。

如何“连接 + 评估”数组名称?

我还希望能在哪些测试检查“这会失败吗?”或“是否存在其他维度?”方面提供帮助。在 C++ 中,因为我只是在学习它。

【问题讨论】:

  • sizeof 是一个操作符,而不是一个函数,所以你可以写sizeof x 来得到x 的大小。将x 放在括号中是多余的。也就是说,你的最后一个陈述应该如何“失败”?无论如何,前进的方法是使用模板,因为有关尺寸的全部信息都包含在arr 的类型中。然后,您可以使用递归来处理数组的每个级别。为此,您需要区分余数是否仍为数组作为停止条件。
  • 你打算用这个循环做什么?如果你把它放在一个函数中以便你可以重用它,很多事情都会出错,尤其是array decay 和代码无法编译。
  • 还有很多比 C++ 中的数组更好的工具。您甚至可以为自己构建一个类,该类是具有任意维数的多维数组。或者使用boost::multi-array,因为他们已经完成了所有工作。
  • @user4581301 我认为课程适合我。但是对于我的代码运行时将是一个非常重要的因素。我的猜测是,数组在保存时会运行得更快并产生更小的文件。由于 C++ 更适用于类,您认为它们在这里可能比数组更有优势吗?
  • 是的,使用std::array(当您知道界限时)或std::vector(当您不知道时)可能与使用[N] 的性能相同new [n]

标签: c++ arrays multidimensional-array


【解决方案1】:

如果您使用的是 c++ 17 编译器,则可以使用类型特征结构 std::rankstd::extent,如下所示

#include <iostream>
#include <type_traits>

template<typename T>
void print_dimension(std::size_t i) {
    if (std::rank_v<T> > 0) {
        std::cout << "Dimension " << i << ":" << std::extent_v<T> << std::endl;
        print_dimension<typename std::remove_extent_t<T>>(i + 1);
    }
}

int main() {
int arr[3][5][10][9] ;
print_dimension<decltype(arr)>(1);
return 0;
}

如果您使用的是 C++ 11/14 编译器,则需要稍作修改

#include <iostream>
#include <type_traits>

template<typename T>
void print_dimension(std::size_t i) {
    if (std::rank<T>::value > 0) {
        std::cout << "Dimension " << i << ":" << std::extent<T>::value << std::endl;
        print_dimension<typename std::remove_extent<T>::type>(i + 1);
    }
}

int main() {
int arr[3][5][10][9] ;
print_dimension<decltype(arr)>(1);
return 0;
}

【讨论】:

  • @Hope 这种方式使用了模板,所以如果你刚开始学习c++可能会比较难理解,但是你可以问问你是否看不懂代码里写的东西
猜你喜欢
  • 2019-01-20
  • 1970-01-01
  • 2014-07-16
  • 1970-01-01
  • 2016-04-09
  • 1970-01-01
  • 2013-04-01
  • 2014-12-22
相关资源
最近更新 更多