回答:
配列と配列サイズを取得した後でベクトルを構築できる場合は、次のように言うことができます。
std::vector<ValueType> vec(a, a + n);
...仮定a
はあなたの配列でn
あり、それに含まれる要素の数です。それ以外の場合は、std::copy()
w / resize()
がうまくいきます。
memcpy()
値がプレーン・オールド・データ(POD)タイプであることが確実でない限り、私は離れたままにします。
また、これらのどれも実際にはforループを回避しないことにも注意してください。これは、コードでそれを表示する必要があるかどうかの問題です。値をコピーする場合、O(n)ランタイムのパフォーマンスは避けられません。
最後に、Cスタイルの配列はほとんどのSTLアルゴリズムにとって完全に有効なコンテナーです。生のポインターはと同等begin()
であり、(ptr + n
)はと同等end()
です。
vec.assign(a, a+n)
。これは、コピーとサイズ変更よりもコンパクトです。
ここには多くの答えがあり、それらのほぼすべてが仕事を成し遂げるでしょう。
ただし、誤解を招くアドバイスがあります。
オプションは次のとおりです。
vector<int> dataVec;
int dataArray[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
unsigned dataArraySize = sizeof(dataArray) / sizeof(int);
// Method 1: Copy the array to the vector using back_inserter.
{
copy(&dataArray[0], &dataArray[dataArraySize], back_inserter(dataVec));
}
// Method 2: Same as 1 but pre-extend the vector by the size of the array using reserve
{
dataVec.reserve(dataVec.size() + dataArraySize);
copy(&dataArray[0], &dataArray[dataArraySize], back_inserter(dataVec));
}
// Method 3: Memcpy
{
dataVec.resize(dataVec.size() + dataArraySize);
memcpy(&dataVec[dataVec.size() - dataArraySize], &dataArray[0], dataArraySize * sizeof(int));
}
// Method 4: vector::insert
{
dataVec.insert(dataVec.end(), &dataArray[0], &dataArray[dataArraySize]);
}
// Method 5: vector + vector
{
vector<int> dataVec2(&dataArray[0], &dataArray[dataArraySize]);
dataVec.insert(dataVec.end(), dataVec2.begin(), dataVec2.end());
}
長い話を短くカットするには、vector :: insertを使用する方法4がbsruthのシナリオに最適です。
ここにいくつかの悲惨な詳細があります:
方法1はおそらく理解するのが最も簡単です。配列から各要素をコピーして、ベクターの後ろにプッシュするだけです。悲しいかな、それは遅いです。ループがあるため(コピー機能に含まれる)、各要素を個別に処理する必要があります。配列とベクトルが連続したブロックであることを知っているという事実に基づいて、パフォーマンスを向上させることはできません。
方法2は、方法1に対して推奨されるパフォーマンス改善です。追加する前に、アレイのサイズを事前に予約してください。大規模な配列の場合、これが役立つ場合があります。ただし、プロファイリングで改善が得られる可能性がある場合(または、イテレーターが無効にならないようにする必要がある場合)にプロファイリングが提案しない限り、ここでの最善のアドバイスは予約を使用しないことです。 Bjarneも同意する。ちなみに、私はこの方法がほとんどの時間で最も遅いことを発見しましたが、方法1よりも通常大幅に遅い理由を包括的に説明するのに苦労しています...
方法3は古い学校の解決策です-問題にCを投げてください!PODタイプで問題なく高速に動作します。この場合、memcpyはベクターの境界の外で機能し、ベクターにサイズが変更されたことを伝える方法がないため、サイズ変更を呼び出す必要があります。醜いソリューション(バイトコピー!)であることは別にして、これはPODタイプでのみ使用できることを覚えておいてください。私はこのソリューションを決して使用しません。
方法4が最善の方法です。それは意味が明確であり、それは(通常)最速であり、どのオブジェクトに対しても機能します。このアプリケーションでこのメソッドを使用することの欠点はありません。
方法5は方法4の微調整です-配列をベクトルにコピーしてから追加します。良いオプション-一般的に高速で明確です。
最後に、配列の代わりにベクトルを使用できることを知っていますよね?関数がCスタイルの配列を期待する場合でも、ベクトルを使用できます。
vector<char> v(50); // Ensure there's enough space
strcpy(&v[0], "prefer vectors to c arrays");
それが誰かを助けることを願っています!
&expr
評価しないように定義されてexpr
おり、アドレスを計算するだけです。また、最後の要素の1つ後のポインタも完全に有効です。
dataVec.insert(dataVec.end(), dataArray, dataArray + dataArraySize);
私にはもっとはっきりと見えます。方法5からも何も得ることができず、コンパイラーがベクトルを再度最適化できなければ、かなり非効率的に見えます。
std :: copyはあなたが探しているものです。
私は自分の回答しか編集できないため、質問に対する他の回答から複合回答を作成します。答えてくださった皆様、ありがとうございました。
std :: copyを使用しても、これはバックグラウンドで繰り返されますが、コードを入力する必要はありません。
int foo(int* data, int size)
{
static std::vector<int> my_data; //normally a class variable
std::copy(data, data + size, std::back_inserter(my_data));
return 0;
}
通常のmemcpyを使用します。これはおそらく基本的なデータ型(つまりint)に最適ですが、構造体やクラスのより複雑な配列には使用できません。
vector<int> x(size);
memcpy(&x[0], source, size*sizeof(int));
memcpyは避けてください。本当に必要な場合を除いて、ポインタ操作をいじる理由はありません。また、POD型(intなど)でのみ機能しますが、構築が必要な型を処理している場合は失敗します。
int dataArray[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };//source
unsigned dataArraySize = sizeof(dataArray) / sizeof(int);
std::vector<int> myvector (dataArraySize );//target
std::copy ( myints, myints+dataArraySize , myvector.begin() );
//myvector now has 1,2,3,...10 :-)
myints
?
さらに別の答えは、「関数が呼び出される回数がわからない」という人が言ったので、ベクトルの挿入メソッドを使用して、値の配列をベクトルの末尾に追加することができます。
vector<int> x;
void AddValues(int* values, size_t size)
{
x.insert(x.end(), values, values+size);
}
ベクトルの実装は、イテレータタイプとタイプ自体に基づいて値を挿入する最良の方法を最適化できるはずなので、この方法が好きです。stlの実装についていくぶん返事をしている。
最速の速度を保証する必要があり、タイプがPODタイプであることがわかっている場合は、Thomasの回答でサイズ変更メソッドをお勧めします。
vector<int> x;
void AddValues(int* values, size_t size)
{
size_t old_size(x.size());
x.resize(old_size + size, 0);
memcpy(&x[old_size], values, size * sizeof(int));
}
上記のメソッドに加えて、std :: Vector.reserve()、std :: Vector.resize()のいずれかを使用するか、ベクターをサイズに合わせて構築し、ベクターに十分な要素があることを確認する必要がありますデータを保持します。そうでない場合、メモリが破損します。これはstd :: copy()またはmemcpy()のいずれにも当てはまります。
これがvector.push_back()を使用する理由です。ベクトルの終わりを超えて書き込むことはできません。
ベクター内のアイテムの大きさがわかっていると仮定します。
std::vector<int> myArray;
myArray.resize (item_count, 0);
memcpy (&myArray.front(), source, item_count * sizeof(int));