boost :: multi_array <>を使用すると同時に、レガシーライブラリにはcスタイルの2次元配列が必要なためです。
2 に答える
T **
Cスタイルの配列ではありません。組み込みのCスタイルの配列は、通常の1D配列にオーバーレイされたインデックス再計算技術によって実装されます。
T **
手動で実装された「マルチレベル」2Dアレイになります。この種の2D配列は、2レベルの実装を使用します。最初のレベルの配列は、実際のデータを含む2番目のレベルの配列を指すポインターの配列です。これは完全に異なるアプローチであり、組み込みアレイとは互換性がありません。
で使用されるメモリレイアウトboost::multi_array<T, 2>
は、組み込みのCスタイルの配列の場合と同じです。つまり、インデックスの再計算によって2Dのふりをする1D配列です。T **
2レベルのメモリ構造は単にに存在しないため、そこからスタイル配列を「抽出」することはできませんboost::multi_array
。
これにより、レガシーライブラリに必要な配列の種類(T **
-style配列またはC-style配列)が問題になります。これらは同じではないためです。
ブーストマルチアレイがプリミティブc++アレイと同じようにレイアウトされている場合、標準的な方法でアクセスできませんか?
c_storage_order
..。
c_storage_orderは、プリミティブC ++多次元配列で使用されるものと同じレイアウトを使用して、つまり最後の次元から最初の次元まで、配列がその要素を格納する必要があることを指定するために使用されます。これは、このライブラリによって提供されるアレイのデフォルトのストレージ順序です。
そして下部に:
このライブラリは、boost :: arrayがCの1次元配列に対して行うように、CスタイルのN次元配列を拡張するという点でboost::arrayに類似しています。
つまり、宣言とアクセスを容易にするためにラッパーを追加するだけですが、内部的には標準の多次元配列のように聞こえます。
やってみました?何か問題がありますか?
編集
先ほど指摘したように、1D配列のようです。しかし、次のようにアクセスできるようです。
#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