2017-08-03 3 views
0
std::string my_func(){ 
    return std::string("..."); 
} 

std::stringは、std::vectorなどで置き換えることができます。一般に、rvが移動され、コピーされていないことをどのように知っていますか?rvが移動され、コピーされていないことをどのように知ることができますか?

+2

生成されたアセンブリ言語コードを読み取ります。 –

+0

これはおそらく移動またはコピーされません。 – juanchopanza

+0

移動またはコピーされます。そして、答えが重要なのは、動かされたときに書かれたものに固執し、むしろ 'void my_func(std :: string & str);')の代わりに – user3600124

答えて

2

移動コンストラクタは、rvalue参照を受け取ります。 rvalue参照は、prvalを扱うときにconstへの左辺参照よりも優先されます。したがって、型が有効な移動コンストラクタを持つ限り、コンパイラは移動コンストラクタを選択し、移動コンストラクタがない場合にのみコピーコンストラクタに戻ります。

この場合、コピーや移動はほとんど行われず、RVOが呼び出され、コールサイトでオブジェクトが直接構築されます。それがあったのかどうかを知る唯一の方法は、アセンブリを検査することです。

guaranteed copy elisionを使用しているC++ 17以降では、ここでコピーや移動が行われないことが実際に保証されています。 はアイデンティティを持っていないとprvalue( "純粋右辺値")と呼ばれているから移動することができます... C++ 11、数式表現でcppreferenceによると

5

。あなたが戻ってきている1(std::string("..."))のような

一時オブジェクトにはアイデンティティを持っていないと、コンパイラはその寿命が終わる前にその状態は使用されないことを検出することができますので、から移動することができます。したがって、コンパイラは、オブジェクトをコピーするよりもオブジェクトを移動させたいと考えます。

しかし、一時的なオブジェクトは、おそらく移動したり、まったく理由戻り値の最適化(RVO)、それはそれ以外に移動することになるストレージにオブジェクトを構築するcopy elision最適化の形式でコピーされません。したがって、std::string str = my_func();を記述する場合、コードはの中に文字列を構築し、それを移動するのではなく、からstrを組み立てるように最適化されている可能性があります。 RVOは、コピー可能および/または移動可能なあらゆる種類のオブジェクトに適用されます。

関連する問題