web-dev-qa-db-ja.com

コピーなしでc ++ std :: vectorを返す?

コピーせずに関数から標準コンテナーを返すことはできますか?

コード例:

std::vector<A> MyFunc();

...

std::vector<A> b = MyFunc();

私が理解している限り、これは戻り値を新しいベクトルbにコピーします。関数に参照を返すようにするか、コピーを回避できるようなものにしますか?

29
static_rtti

コンパイラがNRVOをサポートしている場合、オブジェクトを返す関数で特定の条件が満たされていれば、コピーは作成されません。ありがたいことに、これは最終的に追加されました Visual C++ 2005(v8.0) これは明らかに、コンテナーが大きい場合、パフォーマンスに大きな影響を与える可能性があります。

独自のコンパイラドキュメントでサポートされているかどうかが示されていない場合は、C++コードをアセンブラにコンパイルして(最適化/リリースモードで)、簡単なサンプル関数を使用して何が行われるかを確認できます。

優れた幅広い議論もあります ここ

28
Steve Townsend

const参照にバインドされた右辺値(「一時」)の有効期間は、参照の有効期間の終わりまで延長されます。したがって、そのベクトルを変更する必要がない場合は、次のようにします。

const std::vector<A>& b = MyFunc();

ifベクトルを変更する必要があります。この行がパフォーマンス面でも重要であることの証明(プロファイリングを通じて取得)が得られるまで、最も読みやすい方法でコードを記述します。

それ以外の場合は、右辺値参照を持つC++ 1xに依存し、セマンティクスを「今すぐ実際に」実現し、何もすることなくそのコピーを最適化します。

14
sbi

関数のシグネチャを変更できる場合は、使用できます

std::vector<A>& MyFunc(); 

または

void MyFunc(std::vector<A>& vect);

スマートポインターを返すこともできますが、これにはオブジェクトの新規作成が含まれます。

some_smart_pointer<std::vector<A>> MyFunc();

HTH

2
beezler