2016-01-04 4 views
14

std::moveは次のスニペットで必要ですか?`std :: move`はここで必要ですか?

私の知る限り call()は右辺値参照を受け入れる知っているよう
std::function<void(int)> my_std_function; 

void call(std::function<void(int)>&& other_function) 
{ 
    my_std_function.swap(std::move(other_function)); 
} 

..しかし、右辺値参照は左辺値そのものであることから、swap(std::function<void(int)>&&)を呼び出すために、私はstd::move

と右辺値参照にこれをキャストし直す必要があり

が正しい私の推論ですかstd::moveが、この場合には省略することができます(そしてそれができるなら、なぜですか?)

+1

ここでは、スワップの代わりに演算子=を発行したいと思うようです。そして、はい、移動を使用します。 –

答えて

18

std::function::swapは右辺値参照によりそのパラメータを取りません。それはちょうどregular non-const lvalue referenceです。だからstd::moveは役に立ちません。また、右辺の参照は非const左辺の参照へのバインドが許可されていないため、おそらくコンパイルしないでください。

other_functionもまた、正の値の参照である必要はありません。

11

署名が

void std::function<Sig>::swap(function& other) 

ので、コードがstd::moveでコンパイルするべきではないです(MSVCは、この結合を可能にする拡張機能があります:/)を

あなたはr値の参照を取るように、私は単純な代入と思いますあなたがあなたのケースで何をしたいです:

std::function<void(int)> my_std_function; 

void call(std::function<void(int)>&& other_function) 
{ 
    my_std_function = std::move(other_function); // Move here to avoid copy 
} 
+1

あなたはMSVC2015 – Dean

+2

@Deanの素晴らしい魔法のポイントを見逃しています。このマジックは非常に速いコンピュータを単にそれをインストールするだけで熱いプラスチックのブロックに変えますか? –

+1

@Dean Er、何? rvalue refが非const lvalue refにバインドできるようにするのはなぜ "素晴らしい魔法"ですか?その皮肉でしたか? –

1

あなたは再びあなたがstd::moveを必要とするだろう右辺値を取得する意味—に正しいです。

しかし、swapコールでは、右辺値または右辺値参照は必要ありません—ちょうど普通の 'lvalue ref。

キャストstd::moveがなければいいです。

移動セマンティクスでは、スワップ操作はかなり低レベルです。最も便利な移動は、最終的には一連のスワップによって実装されるため、スワップ自体は移動セマンティクスを使用しないことが理にかなっています。本当に、彼らはどうですか?

3

std::function::swapは非左辺参照をとるため、この場合は違いはありません。それはstd::moveでコンパイルすべきではありません。 other_functionとしてstd::moveを呼び出すため

あなたははあなたそして、右辺値を許可しなかった機能を使用している場合だろう必要性は、それのタイプは右辺値参照であっても、左辺値です。例:

struct Foo { 
    Foo()=default; 
    Foo(const Foo&) { std::cout << "copy" << std::endl; } 
    Foo(Foo&&) { std::cout << "move" << std::endl; } 
}; 

void bar (Foo&& a) { 
    Foo b {a};   //copy 
    Foo c {std::move(a)}; //move 
} 
+0

これは、 'swap()'が参照を取るということだけでなく、重要な情報を追加します。これは本当に問題のポイントではないと思います。 – isanae

関連する問題