2017-02-14 12 views
17

は、私は次のコードをコンパイルしようとしています:ラムダで移動するときに移動コンストラクタが呼び出されないのはなぜですか?

#include <utility> 

struct C2 { 
     C2() = default; 
     C2(C2 const&) = delete; 
     C2(C2&&) = default; 
}; 

int main() { 
     C2 p2; 
     ([p2_1{ std::move(p2) }]() { 
       auto p2_2 = std::move(p2_1); // <--- 
     })(); 
     return 0; 
} 

しかし、これはコンパイルされないのとp2_2への割り当てが削除された機能、すなわちコピーコンストラクタを呼び出していることをエラーが発生します。 p2_1への移動は問題ありません。なぜこれは移動コンストラクタを使用していないのですか?

+0

私はラムダの専門家ではなく、 'p2'を' p2_1'に、 'p2_1'をキャプチャして' p2_1'を 'p2_2'に動かすのではなく、 'p2_2'に直接送信する](http://ideone.com/PsBQMJ)? '[&p2](){auto p2_2 = std :: move(p2); } ' –

+2

@RemyLebeauこれは、私が実際にやっていたことのかなり下のバージョンです。それでも問題が残っている小さなサンプルが出るまで、私は部品を取り外していました。実際のコードでは、ラムダが宣言された関数スコープよりも先にラムダを必要としていたので、キャプチャによるリファレンスはオプションではありませんでした。 – baruch

+0

これは意味があります。 –

答えて

27

ここでキャッチするのは、ラムダが表す匿名クラスタイプのoperator()はデフォルトでconstです。つまり、ラムダのthisconst&なので、p2_1から移動することはできません。何をする必要が今度はあなたがそのメンバーを変異させることができることを意味機能以外のconstを作る

int main() { 
     C2 p2; 
     ([p2_1{ std::move(p2) }]() mutable { 
       auto p2_2 = std::move(p2_1); // <--- 
     })(); 
     return 0; 
} 

ようmutableキーワードを使用しています。これにより、コピーしようとする代わりにp2_1を移動することができます。

+0

これは 'this'もキャプチャするのにも当てはまりますか?私はキャプチャされた 'this'ポインタを使って非const関数を呼び出すことができるようです。 – baruch

+0

@baruchそれは良い質問です。 AFAIKは 'this'を捕捉するときに値の型を保持するので、非constの場合はラムダでは非constになります。 – NathanOliver

+3

@baruch 'this'はconstですが' * this'はconstではありません。これはconstポインタですが、constへのポインタではありません。 – immibis

関連する問題