54

次のコードがあるとします。

#include <vector>
struct A {
    int a;
    int x;
};
int main() {
    using namespace std;
    A a1;
    A a2;
    vector<A> va;
    va.push_back(a1);
    va.push_back(move(a2));
}

std :: listとは異なり、std::vectorの要素は連続して格納されていることを認識しています。上記のコードでは移動されていますが、ベクトルへa2のコピーは実際にはありませんか?との違いは何ですか?a2vava.push_back(a2);va.push_back(move(a2));

4

3 に答える 3

58

あなたの場合、コンパイラが提供するコピーコンストラクタを使用しているため、効果的な違いはありません。移動で構成可能なオブジェクトを使用すると、パフォーマンスに顕著な違いが見られ、コピーに多大な労力がかかります。その場合、を使用push_back(x)するとオブジェクトのコピーが作成されますが、はpush_back(move(x))push_back()の内容を「盗む」可能性があり、使用できない未定義の状態のxままになる可能性があることを示します。x

リストのベクトル(std::vector<std::list<int> >)があり、100,000個の要素を含むリストをプッシュしたい場合を考えてみてください。がないmove()と、リスト構造全体と100,000個の要素すべてがコピーされます。を使用move()すると、一部のポインタやその他の小さなデータがシャッフルされます。これで問題ありません。これははるかに高速になり、全体的なメモリ消費量が少なくて済みます。

于 2012-07-20T04:03:11.263 に答える
22

va.push_back(a2)バージョンを使用vector<T>::push_back(const T&)すると呼び出され、va.push_back(move(a2))バージョンを使用vector<T>::push_back(T&&)すると呼び出されます...

しかし、あなたの場合、パフォーマンスに違いはありません。

15非ユニオンクラスXの暗黙的に定義されたコピー/移動コンストラクターは、そのベースとメンバーのメンバーごとのコピー/移動を実行します。

パラグラフ12.8n3337ドラフト。

于 2012-07-20T03:59:36.927 に答える
0

他の答えが終わっていないことに注意したい。移動コンストラクターは移動されたオブジェクトをゼロ\設定する必要があるため(簡単にコピー可能なオブジェクトがある場合)、があなたの場合?.push_back(move(?))よりも遅くなるということです。これは事実上、2つのオブジェクトを書き込み/コピーしています。?.push_back(?)

于 2016-11-19T17:10:01.897 に答える