の cpp ドキュメントからstd::vector
、次のように表示されます。
void push_back ( const T& x );
push_back
私が渡すオブジェクトのコピーを作成することを理解しています。しかし、なぜ署名はconst T& ?
これを見て、私const
がvector
.
他のオプションは
void push_back(T x);
つまり、値で取得x
します。ただし、これにより (C++03 では) の余分なコピーが作成x
されます (引数内のコピーpush_back
)。x
const 参照で取得すると、これが回避されます。
v.push_back(T())
値渡しの呼び出しのスタックを見てみましょう。
v.push_back(T()); // instance of T
void std::vector<T>::push_back(T x) // copy of T
new (data_[size_ - 1]) T(x) // copy of copy of T
const 参照を取得すると、次のようになります。
v.push_back(T()); // instance of T
void std::vector<T>::push_back(const T &x) // const reference to T
new (data_[size_ - 1]) T(x) // copy of T
C++11 では、(不要ではありますが)x
値を取得し、std::move
それをベクトルに移動するために使用できます。
v.push_back(T()); // instance of T
void std::vector<T>::push_back(T x) // copy of T
new (data_[size_ - 1]) T(std::move(x)) // move the copy of T
@ecatmur が説明する「追加のコピー」を明確にするために、push_back
その引数を値で受け取った場合、オブジェクトから始めることになります。push_back
そのコピーは、そのパラメーターとして渡されます。次に、そのpush_back
コピーを作成してベクター自体に入れます。
の実際の実装はpush_back
参照によって引数を受け取るためpush_back
、元のオブジェクトのコピーとしてベクトル内に新しいオブジェクトを直接作成します。
既に述べたように、移動セマンティクスを使用する C++11 では、引数を値で渡し、その値をその引数からベクトル内の新しいオブジェクトに移動することが可能です (おそらく特に有利ではありません)。ベクトルに入れているものが、たとえば、ほとんどがポインターといくつかの「ブックキーピング」フィールド (割り当てられたメモリの量、現在使用中のメモリの量) を含む文字列である場合、それはほぼ同じくらい効率的です移動は浅いコピーを実行できるため、参照を渡します。ポインターが指すすべてのデータではなく、ポインターとブックキーピング値自体をコピーします。ただし、問題のオブジェクトがすべてのデータを直接保持している (つまり、ポインターではない) 場合、移動はコピーと同じくらい遅くなります。
参照による受け渡しは、すべてのコピーを回避するため、文字列のようなものであっても、一般的にはさらに高速です (このような場合、元のオブジェクトを無効にすることはできません)。また、C++11 だけでなく、C++98/03 で動作するという小さな利点もあります。
あなたobject
がプッシュしたものは、参照によって渡されて回避されますextra copy
。よりコピーが配置されますvector
。