ストレージのサイズが事前にわかっている場合は、ネストされたベクトルを使用しないでください。たとえば、最初のインデックスのサイズを 6 にする必要があり、決して変更されないなど、特定の理由がある場合です。単純な配列を使用してください。いっそのこと、使用します。そうすれば、単純な配列を持つことのすべての利点 (多次元になると大量のスペースを節約する) と、実際のオブジェクトのインスタンス化を持つことの利点が得られます。boost::array
ストレージが長方形でなければならない場合は、ネストされたベクトルを使用しないでください。つまり、1 つ以上の寸法のサイズを変更する可能性がありますが、すべての「行」はある時点で同じ長さでなければなりません。を使用します。そうすれば、「このストレージは長方形です」と文書化し、大量のスペースを節約しながら、サイズ変更機能、実際のオブジェクトを持つ利点などを得ることができます。boost::multi_array
重要なstd::vector
のは、(a) サイズ変更可能であり、(b) 正しい型である限り、その内容を少しも気にしないことです。これは、 がある場合vector<vector<int> >
、すべての「行ベクトル」は、すべて同じ長さであることを強制したい場合でも、それらの長さに関する独自の簿記情報を維持する必要があることを意味します。また、それらはすべて個別のメモリ割り当てを管理することを意味し、パフォーマンス (キャッシュ動作) を損ない、std::vector
再割り当て方法のためにさらに多くのスペースを浪費します。boost::multi_array
サイズを変更したいかもしれないことを期待して設計されていますが、要素 (行、2 次元配列の場合は面、3 次元配列の場合は面など) を最後に追加してサイズを常に変更することはありません。std::vector
動作が遅くならないように (潜在的に) スペースを浪費するように設計されています。boost::multi_array
は、スペースを節約し、すべてをメモリ内できちんと整理できるように設計されています。
それは言った:
はい、ベクトルにインデックスを付ける前に何かをする必要があります。std::vector
そこに何かを保存したいので、魔法のようにインデックスが存在するようになることはありません。ただし、これは簡単に処理できます。
最初に適切な量のゼロでベクトルをデフォルトで初期化してから、(size_t n, const T& value = T())
コンストラクターを使用してそれらを置き換えることができます。あれは、
std::vector<int> foo(10); // makes a vector of 10 ints, each of which is 0
「デフォルトで構築された」int の値は 0 であるためです。
あなたの場合、適切なサイズのサブベクトルを作成し、コンストラクターにそれらをコピーさせることにより、各次元のサイズを指定する必要があります。これは次のようになります。
typedef vector<float> d1;
typedef vector<d1> d2;
typedef vector<d2> d3;
typedef vector<d3> d4;
d4 result(2, d3(7, d2(480, d1(31))));
つまり、名前のないd1
はサイズ 31 で構築され、 defaultを初期化するために使用されます。これはd2
、 default を初期化するためにd3
使用されますresult
。
他のアプローチもありますが、たくさんのゼロを開始したいだけの場合は、はるかに扱いにくいです。ただし、ファイルからデータ セット全体を読み取る場合は、次のようにします。