43

C++ 11 ではstd::array、配列よりも悪くない連続したストレージとパフォーマンスを持つように定義されていますが、標準のさまざまな要件が std::array が通常と同じサイズとメモリ レイアウトを持っていることを意味するかどうかは判断できません。配列。それは信頼できますか、sizeof(std::array<int,N>) == sizeof(int)*Nそれとも実装固有ですか?

特に、これはあなたが期待するように動作することが保証されています:

std::vector< std::array<int, N> > x(M);
typedef (*ArrayPointer)[N];
ArrayPointer y = (ArrayPointer) &x[0][0];
// use y like normal multidimensional array

私が試した2つのコンパイラ(GNUとIntel)で動作します。さらに、私が見つけることができるすべてのサードパーティのドキュメント (このように) は、std::array はプレーン配列と同じくらいメモリ効率が高く、連続した要件と組み合わせると、同一のメモリ レイアウトが必要であることを意味すると述べています。ただし、この要件は標準では見つかりません。

4

1 に答える 1

30

ほぼ必須です。具体的には、§23.3.2.1/2 は次のように述べています。

配列は、次の構文で初期化できる集約 (8.5.1) です。

array<T, N> a = { initializer-list };

whereinitializer-listは、型が T に変換可能な最大 N 個の要素のコンマ区切りリストです。

これは集合体であるため、初期化子リスト内のデータを正しい形式に変換するために、どのような種類のコンストラクターも使用できません。つまり、保存できるのは値そのものだけです。

事前定義された値に設定された追加のメモリなど、指定されたデータに続くある種の補助データを格納すること可能だと思います。そのため、配列の末尾を超えて書き込むと、おそらくそのデータが変更されます。std::arrayコンパイラ/ランタイムは、シャットダウン時にこれらの値をチェックし、値を変更した場合は、コードの未定義の動作を報告します。

コンパイラstd::array組み込み配列とは異なる方法でパディング/アラインメントを行う可能性もあります。これが望ましいとさえ言える明白な例の 1 つは、Intel の SSE 命令で使用するデータなど、スーパーアライメント要件をサポートすることです。ビルトイン配列はスーパーアラインメントをサポートできませんが、 の仕様はそれを許容するのにかろうじて緩いのではないかと思います。std::array

結論: いくつの可能性が存在するかについての質問に入ることなく、質問してstd::arrayいるルールに従う必要がないことは明らかです。

于 2013-09-30T20:50:49.047 に答える