假设我有一个N维boost :: multi_array(为简单起见,类型为int),该N位置在编译时是已知的,但可以变化(即,是非类型模板参数)。假设所有尺寸的大小相等m。
N
m
typedef boost::multi_array<int, N> tDataArray; boost::array<tDataArray::index, N> shape; shape.fill(m); tDataArray A(shape);
现在,我想遍历中的所有条目A,例如打印它们。例如,如果N为2,我想我会写这样的东西
A
boost::array<tDataArray::index, 2> index; for ( int i = 0; i < m; i++ ) { for ( int j = 0; j < m; j++ ) { index = {{ i, j }}; cout << A ( index ) << endl; } }
我使用了索引对象来访问元素,因为我认为这比[]操作符更灵活。
但是我怎么能在不知道尺寸数的情况下写这个呢N?有内置的方法吗?multi_array的文档不太清楚存在哪种类型的迭代器,等等。还是我不得不诉诸于带有自定义指针的自定义方法,从指针计算索引等?如果是这样的话,那么关于这种算法的建议如何?
好的,根据注释中已经提到的Google小组讨论以及库本身的示例之一,这是一个可能的解决方案,它使您可以在单个循环中遍历多数组中的所有值 并 提供一个检索这些元素中的每个元素的索引的方式(以防其他情况(如我的情况)所需)。
#include <iostream> #include <boost/multi_array.hpp> #include <boost/array.hpp> const unsigned short int DIM = 3; typedef double tValue; typedef boost::multi_array<tValue,DIM> tArray; typedef tArray::index tIndex; typedef boost::array<tIndex, DIM> tIndexArray; tIndex getIndex(const tArray& m, const tValue* requestedElement, const unsigned short int direction) { int offset = requestedElement - m.origin(); return(offset / m.strides()[direction] % m.shape()[direction] + m.index_bases()[direction]); } tIndexArray getIndexArray( const tArray& m, const tValue* requestedElement ) { tIndexArray _index; for ( unsigned int dir = 0; dir < DIM; dir++ ) { _index[dir] = getIndex( m, requestedElement, dir ); } return _index; } int main() { double* exampleData = new double[24]; for ( int i = 0; i < 24; i++ ) { exampleData[i] = i; } tArray A( boost::extents[2][3][4] ); A.assign(exampleData,exampleData+24); tValue* p = A.data(); tIndexArray index; for ( int i = 0; i < A.num_elements(); i++ ) { index = getIndexArray( A, p ); std::cout << index[0] << " " << index[1] << " " << index[2] << " value = " << A(index) << " check = " << *p << std::endl; ++p; } return 0; }
输出应为
0 0 0 value = 0 check = 0 0 0 1 value = 1 check = 1 0 0 2 value = 2 check = 2 0 0 3 value = 3 check = 3 0 1 0 value = 4 check = 4 0 1 1 value = 5 check = 5 0 1 2 value = 6 check = 6 0 1 3 value = 7 check = 7 0 2 0 value = 8 check = 8 0 2 1 value = 9 check = 9 0 2 2 value = 10 check = 10 0 2 3 value = 11 check = 11 1 0 0 value = 12 check = 12 1 0 1 value = 13 check = 13 1 0 2 value = 14 check = 14 1 0 3 value = 15 check = 15 1 1 0 value = 16 check = 16 1 1 1 value = 17 check = 17 1 1 2 value = 18 check = 18 1 1 3 value = 19 check = 19 1 2 0 value = 20 check = 20 1 2 1 value = 21 check = 21 1 2 2 value = 22 check = 22 1 2 3 value = 23 check = 23
因此内存布局从外部索引到内部索引。请注意,该getIndex函数依赖于boost :: multi_array提供的默认内存布局。如果更改了阵列基础或存储顺序,则必须进行调整。
getIndex