web-dev-qa-db-ja.com

std :: vector:をコピーすると、代入またはstd :: copyが優先されますか?

2つのベクターがあります。

_std::vector<int> v1, v2;

// Filling v1
...
_

そして今、_v1_を_v2_にコピーする必要があります。好む理由はありますか

_v2 = v1;_

std::copy (v1.begin(), v1.end(), v2.begin());

(またはその逆)?

50
Violet Giraffe

一般的に私は_v2 = v1_を強く好むでしょう:

  1. それは短く、意図をより明確にします
  2. _std::copy_の長さが_v2_と同じ長さでない場合、_v1_は機能しません(サイズを変更しないため、古い要素の一部を保持します(v2.size() > v1.size()およびプログラムの最悪の場合の別の場所で使用されるいくつかのランダムデータを上書きします
  3. _v1_の有効期限が近づいている(そしてC++ 11を使用している)場合、moveの内容に簡単に変更できます
  4. 実装者がパフォーマンス上の利点を与える場合は、おそらく_std::copy_を内部で使用するため、パフォーマンス上の割り当ては_std::copy_より遅くなることはほとんどありません。

結論として、_std::copy_は表現力が低く、間違った動作をする可能性があり、さらに高速ではありません。したがって、ここで実際に使用する理由はありません。

64
Grizzly

std::copyの呼び出しは、宛先ベクトルの終わりを超えてアイテムにアクセスしようとする場合があります。

割り当てを使用します。

最適化を行うのはあなたの仕事ではありません。それはライブラリ作成者の責任であり、最終的にはコンパイラの責任です。

コードを作成することができます任意に高速正確である必要がない場合。

ただし、copyの場合、それがさらに高速であるかどうかはかなり疑わしく、一般的な場合には確かに正しくありません。

10

v2が十分に大きくない場合、copyをそのまま使用すると、バッファーオーバーランが発生します。

v2でPush_backを呼び出す逆挿入反復子を使用できます。ただし、v1の大きさによっては、複数の再割り当てが発生する可能性があります。

copy(v1.begin(), v1.end(), back_inserter(v2));

vectorに物事を正しく管理させる方が良いでしょう。 vector::assignと同様に、割り当て演算子はこれを行います。

v2.assign(v1.begin(), v1.end());

割り当て演算子がvector::assignの観点から実装されているという感想があります。

9
Peter Wood

短いです。

std::copyは、主にコンテナのセクションをコピーするためのものです。コンテナ全体をコピーする必要がある場合は、コピーコンストラクタを使用することもできます。

2
Symaxion

割り当て、断然。より一般的には、ベクターのサイズが変更される場合、またはベクターのコンテンツ全体が変更される場合は、メンバー関数を優先する必要があります。唯一の時間std::copyは、ベクトル内の小さな範囲のみを完全に置換する場合に適切です。

2
James Kanze

割り当てはより明確で、内部的にstd::copy(またはunitizalized_copy_M_allocate_and_copyのサイズと容量に応じて)を使用するため、パフォーマンスは同じです。

1
FredericS