19

ご挨拶、

次の2行の短縮コードを使用して、あるベクトル(vec1)から別のベクトル(vec2)へのコピーを実行しようとしています(完全なテストアプリが続きます)。

vec2.reserve( vec1.size() );
copy(vec1.begin(), vec1.end(), vec2.begin());

vec2の呼び出しはベクトルvec2の容量を設定しますが、vec2へのデータのコピーはvec1からvec2への値を入力しないようです。

copy()関数をpush_back()の呼び出しに置き換えると、期待どおりに機能します。

ここで何が欠けていますか?

ご協力いただきありがとうございます。vectest.cppテストプログラムとそれに続く結果の出力は次のとおりです。

コンパイラ:cygwin上のgcc3.4.4。

ナット

/**
 * vectest.cpp
 */

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> vec1;
    vector<int> vec2;

    vec1.push_back(1);
    vec1.push_back(2);
    vec1.push_back(3);
    vec1.push_back(4);
    vec1.push_back(5);
    vec1.push_back(6);
    vec1.push_back(7);

    vec2.reserve( vec1.size() );
    copy(vec1.begin(), vec1.end(), vec2.begin());

    cout << "vec1.size()     = " << vec1.size() << endl;
    cout << "vec1.capacity() = " << vec1.capacity() << endl;

    cout << "vec1: ";
    for( vector<int>::const_iterator iter = vec1.begin(); iter < vec1.end(); ++iter ) {
        cout << *iter << " ";
    }
    cout << endl;

    cout << "vec2.size()     = " << vec2.size() << endl;
    cout << "vec2.capacity() = " << vec2.capacity() << endl;
    cout << "vec2: ";
    for( vector<int>::const_iterator iter = vec2.begin(); iter < vec2.end(); ++iter ) {
        cout << *iter << endl;
    }

    cout << endl;
}

出力:

vec1.size()     = 7
vec1.capacity() = 8
vec1: 1 2 3 4 5 6 7 
vec2.size()     = 0
vec2.capacity() = 7
vec2: 
4

5 に答える 5

35

ベクトルが同じタイプの場合は、コピーの作成またはコピーの割り当てを使用します。

vec2(vec1);
vec2 = vec1;

ベクトルが完全に同じでない場合(おそらく、異なるアロケータか何か、またはvec1が両端キューである場合)、本当に必要なのは、範囲ベースのコンストラクターまたは範囲ベースの割り当てです。

vec2(vec1.begin(), vec1.end()); // range-based constructor

vec2.assign(vec1.begin(), vec1.end()); // range-based assignment

でそれを行うことを主張する場合std::copy、適切な方法は次のとおりです。

copy(vec1.begin(), vec1.end(), back_inserter(vec2));

スペースを予約しても割り当て可能にはなりません。copy各要素を新しい値に割り当てることで機能します。したがってvec2.size()、少なくともvec1.size()あなたの場合と同じ大きさである必要があります。呼び出しreserveは、実際にはベクトルのサイズを変更するのではなく、その容量だけを変更します。

著書EffectiveSTLの中で、Scott Meyersは、挿入のためのstd :: copyのほぼすべての使用を、範囲ベースのメンバー関数に置き換える必要があると主張しています。私はあなたがコピーを手に入れることを提案します、それは素晴らしい参考資料です!

于 2009-07-14T22:58:04.433 に答える
27

他の回答やコメントに記載されているように、これにはベクターの組み込み機能を使用する必要があります。だが:

要素をreserve()作成すると、ベクトルは(少なくとも?)その数の要素に十分なスペースを割り当てます。要素はベクトルに存在しませんが、メモリを使用する準備ができています。push_back()メモリがすでに割り当てられているため、これにより速度が上がる可能性があります。

resize()ベクトルを作成すると、それらの要素に十分なスペースが割り当てられますが、ベクトルにも追加されます

したがって、ベクトルのサイズを100に変更すると、要素0〜99にアクセスできますが、100個の要素を予約すると、それらはまだ挿入されておらず、すぐに使用できます。

あなたが欲しいものはこのようなものです:

vec2.reserve( vec1.size() );
copy(vec1.begin(), vec1.end(), std::back_inserter(vec2));

std::back_inserterで定義されています<iterator>

于 2009-07-14T23:14:13.933 に答える
20

なぜ:vec2 = vec1;

于 2009-07-14T22:59:59.857 に答える
4

私の意見では、最も簡単な方法は次のstd::vector::insert方法を使用することです。

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

std :: vector :: insertを参照)

于 2013-01-24T10:47:56.877 に答える
3

予約をresize()に変更します。

vec2.resize(vec1.size(), '\0');
copy(vec1.begin(), vec1.end(), vec2.begin());

それがあなたが必要とする修正だと思います。

違いについて詳しく説明することはできませんが、基本的にreserve()は十分なスペースがあることを確認し、resize()は実際にそこに何かを挿入します。

于 2009-07-14T22:58:55.350 に答える