C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++でベクトル(vector)をコピーする5つの方法

C++で std::vector を別のベクトルにコピーする方法は複数あります。本記事では、代表的な5つの手法をコード例とともに解説します。

方法1: std::copy を使う

std::copy は、あるベクトルの要素を別のベクトルへコピーするための標準ライブラリ関数です。ヘッダー <algorithm> に定義されています。

構文

std::copy(first_iterator_o, last_iterator_o, back_inserter());

first_iterator_o = コピー元ベクトルの先頭イテレータ
last_iterator_o  = コピー元ベクトルの末尾イテレータ
back_inserter()  = 要素を末尾から挿入するためのイテレータアダプタ

アルゴリズム

Begin
    ベクトル型の v1 を宣言し、配列形式で値を初期化する。
    ベクトル型の v2 を宣言する。
    copy(v1.begin(), v1.end(), back_inserter(v2)) を呼び出し、
    v1 の全要素を v2 へコピーする。
    「v1 vector elements are :」と出力し、v1 の全要素を表示する。
    「v2 vector elements are :」と出力し、v2 の全要素を表示する。
End.

サンプルコード

#include <iostream>
#include <vector>
#include <algorithm>   // copy() 用
#include <iterator>    // back_inserter() 用
using namespace std;

int main() {
    vector<int> v1{ 7, 6, 4, 5 };
    vector<int> v2;

    // v1 の全要素を v2 の末尾へ挿入しながらコピー
    copy(v1.begin(), v1.end(), back_inserter(v2));

    cout << "v1 vector elements are : ";
    for (int i = 0; i < v1.size(); i++)
        cout << v1[i] << " ";
    cout << endl;

    cout << "v2 vector elements are : ";
    for (int i = 0; i < v2.size(); i++)
        cout << v2[i] << " ";
    cout << endl;

    return 0;
}

実行結果

v1 vector elements are : 7 6 4 5
v2 vector elements are : 7 6 4 5

この方法では、既存の要素を持つベクトルにも追記できるのが特徴です(push_back 相当の動作で要素が追加されます)。

方法2: assign() メソッドを使う

ベクトルが持つ assign() メンバ関数を使っても、v1 の内容を v2 へコピーできます。既存の要素はすべて置き換えられます。

構文

std::vector::assign(first_iterator_o, last_iterator_o);

first_iterator_o = コピー元ベクトルの先頭イテレータ
last_iterator_o  = コピー元ベクトルの末尾イテレータ

アルゴリズム

Begin
    ベクトル v1 を要素で初期化する。
    別のベクトル v2 を宣言する。
    assign() を呼び出して、v1 の要素を v2 へコピーする。
    v1 の要素を出力する。
    v2 の要素を出力する。
End.

サンプルコード

#include <iostream>
#include <vector>      // vector 用
#include <algorithm>   // copy() / assign() 関連
#include <iterator>    // back_inserter() 用
using namespace std;

int main() {
    vector<int> v1{7, 6, 4, 5};
    vector<int> v2;

    // assign() で v1 の全要素を v2 へコピー
    v2.assign(v1.begin(), v1.end());

    cout << "v1 vector elements are : ";
    for (int i = 0; i < v1.size(); i++)
        cout << v1[i] << " ";
    cout << endl;

    cout << "v2 vector elements are : ";
    for (int i = 0; i < v2.size(); i++)
        cout << v2[i] << " ";
    cout << endl;

    return 0;
}

実行結果

v1 vector elements are : 7 6 4 5
v2 vector elements are : 7 6 4 5

方法3: 代入演算子「=」を使う

最もシンプルな方法です。代入演算子 = を使えば、v1 の全要素が v2 にディープコピーされます。

アルゴリズム

Begin
    ベクトル v1 を要素で初期化する。
    別のベクトル v2 を宣言する。
    代入演算子「=」で v1 の要素を v2 へコピーする。
    v1 の要素を出力する。
    v2 の要素を出力する。
End.

サンプルコード

#include <iostream>
#include <vector>      // vector 用
using namespace std;

int main() {
    vector<int> v1{7, 6, 4, 5};
    vector<int> v2;

    // 代入演算子でコピー
    v2 = v1;

    cout << "v1 vector elements are : ";
    for (int i = 0; i < v1.size(); i++)
        cout << v1[i] << " ";
    cout << endl;

    cout << "v2 vector elements are : ";
    for (int i = 0; i < v2.size(); i++)
        cout << v2[i] << " ";
    cout << endl;

    return 0;
}

実行結果

v1 vector elements are : 7 6 4 5
v2 vector elements are : 7 6 4 5

方法4: push_back() を使う(反復処理によるコピー)

ループでコピー元の各要素を取り出し、push_back() でコピー先へ1つずつ追加していく、最も基本的な反復方式です。

アルゴリズム

Begin
    ベクトル v1 を要素で初期化する。
    別のベクトル v2 を宣言する。
    for ループを使い、push_back() によって
    第1ベクトルの要素を第2ベクトルへ順次コピーする。
    v1 の要素を出力する。
    v2 の要素を出力する。
End.

サンプルコード

#include <iostream>
#include <vector>      // vector 用
using namespace std;

int main() {
    vector<int> v1{7, 6, 4, 5};
    vector<int> v2;

    // ループで1要素ずつ push_back してコピー
    for (int i = 0; i < v1.size(); i++)
        v2.push_back(v1[i]);

    cout << "v1 vector elements are : ";
    for (int i = 0; i < v1.size(); i++)
        cout << v1[i] << " ";
    cout << endl;

    cout << "v2 vector elements are : ";
    for (int i = 0; i < v2.size(); i++)
        cout << v2[i] << " ";
    cout << endl;

    return 0;
}

実行結果

v1 vector elements are : 7 6 4 5
v2 vector elements are : 7 6 4 5

方法5: コンストラクタでコピーする

ベクトルを宣言するときに、コピー元を引数として渡す方法です。コピーコンストラクタにより、全要素がディープコピーされます。

アルゴリズム

Begin
    ベクトル v1 を要素で初期化する。
    ベクトル v2 を宣言し、コンストラクタに v1 を渡すことで
    全要素をディープコピーする。
    v1 の要素を出力する。
    v2 の要素を出力する。
End.

サンプルコード

#include <iostream>
#include <vector>      // vector 用
using namespace std;

int main() {
    vector<int> v1{7, 6, 4, 5};

    // コピーコンストラクタで宣言と同時にコピー
    vector<int> v2(v1);

    cout << "v1 vector elements are : ";
    for (int i = 0; i < v1.size(); i++)
        cout << v1[i] << " ";
    cout << endl;

    cout << "v2 vector elements are : ";
    for (int i = 0; i < v2.size(); i++)
        cout << v2[i] << " ";
    cout << endl;

    return 0;
}

実行結果

v1 vector elements are : 7 6 4 5
v2 vector elements are : 7 6 4 5

まとめ:どの方法を選ぶべきか?

  • 最も簡潔: 代入演算子「=」(方法3)またはコンストラクタ(方法5)
  • 既存ベクトルへの追記: std::copy + back_inserter(方法1)
  • 内容の完全な置き換え: assign()(方法2)
  • 細かい制御が必要な場合: push_back() ループ(方法4)

用途に応じて適切な手法を選択することで、可読性とパフォーマンスの両立が可能になります。なお、これらすべての方法はディープコピーを行うため、コピー後は元のベクトルと独立した新しいインスタンスとして扱われます。

  1. C++の型推論とは?autoキーワードの基本と使い方をわかりやすく解説

    型推論(Type Inference)とは、プログラミング言語において式のデータ型を自動的に判別する機能のことです。この機能は、強い静的型付けを持つ一部の言語に備わっています。 C++では、C++11で追加されたautoキーワードを使うことで、自動的な型推論が可能になります。これにより、開発者は複雑な型名を明示的に書く必要がなくなり、コードがシンプルで読みやすくなります。 autoキーワードの活用例 たとえば、vectorの要素を走査するイテレータを作成したい場合、従来は std::vector<int>::iterator という長い型名を記述する必要がありました。しかし、aut

  2. C++のコピーコンストラクタとは?仕組みと実装方法をサンプルコード付きで解説

    コピーコンストラクタは、コンストラクタの一種です。同じクラスのオブジェクトを受け取り、その値を使って新しいオブジェクトを生成・初期化します。もしクラス内でコピーコンストラクタが定義されていない場合、コンパイラが自動的にデフォルトのコピーコンストラクタを生成します。ただし、ポインタ変数や動的メモリ確保(new/delete)を持つクラスでは、デフォルトのコピーは浅いコピー(shallow copy)となり、同じメモリ領域を複数のオブジェクトが参照してしまう問題が発生します。そのため、このようなクラスでは独自のコピーコンストラクタを定義することが必須となります。コピーコンストラクタのサンプルプログ