12

の cpp ドキュメントからstd::vector、次のように表示されます。

void push_back ( const T& x );

push_back私が渡すオブジェクトのコピーを作成することを理解しています。しかし、なぜ署名はconst T& ?これを見て、私constvector.

4

3 に答える 3

15

他のオプションは

void push_back(T x);

つまり、値で取得xします。ただし、これにより (C++03 では) の余分なコピーが作成xされます (引数内のコピーpush_back)。xconst 参照で取得すると、これが回避されます。

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
于 2012-08-01T15:28:19.723 に答える
9

@ecatmur が説明する「追加のコピー」を明確にするために、push_backその引数を値で受け取った場合、オブジェクトから始めることになります。push_backそのコピーは、そのパラメーターとして渡されます。次に、そのpush_backコピーを作成してベクター自体に入れます。

の実際の実装はpush_back参照によって引数を受け取るためpush_back、元のオブジェクトのコピーとしてベクトル内に新しいオブジェクトを直接作成します。

既に述べたように、移動セマンティクスを使用する C++11 では、引数を値で渡し、その値をその引数からベクトル内の新しいオブジェクトに移動することが可能です (おそらく特に有利ではありません)。ベクトルに入れているものが、たとえば、ほとんどがポインターといくつかの「ブックキーピング」フィールド (割り当てられたメモリの量、現在使用中のメモリの量) を含む文字列である場合、それはほぼ同じくらい効率的です移動は浅いコピーを実行できるため、参照を渡します。ポインターが指すすべてのデータではなく、ポインターとブックキーピング値自体をコピーします。ただし、問題のオブジェクトがすべてのデータを直接保持している (つまり、ポインターではない) 場合、移動はコピーと同じくらい遅くなります。

参照による受け渡しは、すべてのコピーを回避するため、文字列のようなものであっても、一般的にはさらに高速です (このような場合、元のオブジェクトを無効にすることはできません)。また、C++11 だけでなく、C++98/03 で動作するという小さな利点もあります。

于 2012-08-01T15:44:07.473 に答える
8

あなたobjectがプッシュしたものは、参照によって渡されて回避されますextra copy。よりコピーが配置されますvector

于 2012-08-01T15:25:40.390 に答える