18

C ++ 11では、値で返すのは正しいとよく言わstd::vectorれます。

C ++ 03では、RVOがコピーを最適化する必要があるため、これはほとんど当てはまりました。しかし、それはほとんどの開発者を怖がらせるはずです。

  • C ++ 11では、返されたstd::vectorローカル変数は常に移動されますか?
  • そのベクトルがローカル変数自体ではなくローカル変数のメンバーである場合はどうなりますか?
  • 明らかに、グローバル変数を返すことは移動されません。他にどのような場合に移動されませんか?
4

2 に答える 2

15

まず、以前にコピーを削除できたときはいつでも、今でもコピーを削除でき、同じ状況で移動を削除できます。この投稿の残りの部分では、何らかの理由でエリジオンが発生しないと仮定します(コンパイラーの作成者が悪い意味で怠惰だったふりをします)。

C ++ 11では、返されたstd :: vectorローカル変数は常に移動されますか?

std::moveコピーの省略の基準が満たされるか、変数が明示的にdになるたび。

そのベクトルがローカル変数自体ではなくローカル変数のメンバーである場合はどうなりますか?

std::move明示的にdしない限り、移動されません。

明らかに、グローバル変数を返すことは移動されません。他にどのような場合に移動されませんか?

コピーの省略の基準が満たされておらず、変数が明示的に満たされていない場合は常にstd::moved。

それらのどれも、値で返さない正当な理由ではありません。値が自動的に移動されない場合でも、。を使用して値を強制できるため、値による戻りは問題ありませんstd::move

于 2012-06-28T15:18:44.067 に答える
8

C ++ 11では、返されたstd::vectorローカル変数は常に移動されますか?

ローカル変数の場合、値によるパラメーターであっても、コンパイラーは常に最初にそれを移動しようとする必要があります(基準が満たされている場合でも、何らかの理由で移動もコピーも省略できない場合)。それが失敗した場合は、コピーを使用して再試行します。

§12.8 [class.copy] p32

ソースオブジェクトが関数パラメーターであり、コピーされるオブジェクトが左辺値で指定されていることを除いて、コピー操作の省略基準が満たされている、または満たされる場合、コピーのコンストラクターを選択するためのオーバーロード解決は次のようになります。最初は、オブジェクトが右辺値で指定されているかのように実行されます。オーバーロード解決が失敗した場合、または選択したコンストラクターの最初のパラメーターのタイプがオブジェクトのタイプへの右辺値参照ではない場合(おそらくcv修飾)、オブジェクトを左辺値と見なして、オーバーロード解決が再度実行されます。[注:この2段階の過負荷解決は、コピーの省略が発生するかどうかに関係なく実行する必要があります。省略が実行されない場合に呼び出されるコンストラクターを決定し、呼び出しが省略された場合でも、選択されたコンストラクターにアクセスできる必要があります。—エンドノート]

そのベクトルがローカル変数自体ではなくローカル変数のメンバーである場合はどうなりますか?

サブオブジェクトはコピーの省略の基準を満たしていないため、移動は試行されません。(これはばかげています、私見ですが、現在はそうです。サブオブジェクトがローカルであれば完全にうまく移動できるので、2つをリンクする必要はないと思います。)

明らかに、グローバル変数を返すことは移動されません。他にどのような場合に移動されませんか?

参照は明らかに移動されません。それ以外は何も考えられません。

于 2012-06-28T15:22:45.247 に答える