因为我想使用 boost::multi_array<>,同时,遗留库需要 c 样式的 2d 数组。
2 回答
T **
不是C 样式的数组。内置 C 样式数组是通过覆盖在普通一维数组上的索引重新计算技术实现的。
T **
将是一个手动实现的“多级”二维数组。这种二维数组使用两级实现,第一级数组是指向包含实际数据的第二级数组的指针数组。这是一种完全不同的方法,与内置数组不兼容。
所使用的内存布局boost::multi_array<T, 2>
与内置 C 样式数组相同,即它是一个通过索引重新计算“假装”为 2D 的 1D 数组。您不能从中“提取” T **
-style 数组,因为两级内存结构根本不存在于boost::multi_array
.
这实际上提出了遗留库需要哪种数组的问题:T **
-style 数组或 C-style 数组,因为它们不一样。
如果 boost multi 数组的布局方式与原始 c++ 数组相同,那么您不能以标准方式访问它吗?
c_storage_order
...
c_storage_order 用于指定数组应使用与原始 C++ 多维数组相同的布局来存储其元素,即从最后一维到第一维。这是此库提供的数组的默认存储顺序。
在底部:
这个库与 boost::array 类似,因为它增加了 C 风格的 N 维数组,就像 boost::array 对 C 一维数组所做的那样。
这意味着它只是添加了包装器以便于声明和访问,但在引擎盖下它听起来像标准的多维数组。
你有没有尝试过?你看有什么问题吗?
编辑
正如之前指出的,它似乎是一个一维数组。但似乎可以像这样访问它:
#include <boost/multi_array.hpp>
void f( int * arr )
{
std::cout << __PRETTY_FUNCTION__ << " start" << std::endl;
for( int y = 0; y != 2; ++y )
{
for ( int x = 0; x != 4; ++x )
{
// std::cout << arr[x][y] << "," ; // compiler does not like
std::cout << arr[ x + ( y * 4 ) ] << "," ;
}
std::cout << std::endl;
}
std::cout << __PRETTY_FUNCTION__ << " end" << std::endl;
}
和
void multi()
{
typedef boost::multi_array< int, 2 > arr_t;
typedef arr_t::index index;
arr_t a( boost::extents[2][4], boost::c_storage_order() );
int v( 0 );
for ( index i = 0; i != 2; ++i )
for( index j = 0; j != 4; ++j )
{
a[i][j] = ++v;
}
v = 0;
for ( index i = 0; i != 2; ++i )
for( index j = 0; j != 4; ++j )
{
assert( a[i][j] == ++v );
}
for ( index i = 0; i != 2; ++i )
{
for( index j = 0; j != 4; ++j )
{
std::cout << a[i][j] << "," ;
}
std::cout << std::endl;
}
f( a.data() );
}
输出:
1,2,3,4,
5,6,7,8,
void f(int*) start
1,2,3,4,
5,6,7,8,
void f(int*) end