2017-12-28 39 views
3

は、ここで私は、エラーを生成するサンプルコードです:std :: move()を使ってコピーできないオブジェクトをキャプチャすると、ラムダは移動できないのはなぜですか?

#include <functional> 
using namespace std; 

struct S { 
    S() = default; 
    S(const S&) = delete; 
    S(S&&) = default; 
    S& operator=(const S&) = delete; 
    S& operator=(S&&) = delete; 
}; 

template <typename F> 
void post(F&& func) 
{ 
    function<void()> f{forward<F>(func)}; 
} 

int main() 
{ 
    S s; 
    post([s2 = move(s)] { }); 
} 

main()でラムダの内部では、私はstd::move()を使用して、ローカル変数sをキャプチャします。 post()を呼び出す前に、s2は移動が正常に構築されている必要があります。

しかし、post()の内部では、fは、このラムダのタイプを基準にして構築することはできません。

削除した場合、s2 = move(s),fはこの正の値のリファレンスで構成できます。

s2 = move(s)を追加するとラムダが移動しないのはなぜですか?

ここでは、coliruを試してみるlinkです。

+0

@LưuVĩnhPhúc、なぜ私の質問に嫌ったか教えてください。 –

+0

私はそれが嫌いだと思いますか?文法ハイライトのタグをつけるだけです。 –

+0

申し訳ありませんが、私は改訂履歴を誤解し、質問に-1を付けたと思いました。 –

答えて

6

あなたのラムダは移動キャプチャを行うことで移動不可能になりません。しかし、それはコピー不可になってしまい、それが問題になります。

std::functionは、付属のファンクタをそれ自身に移動することをサポートしていません。常にコピーを行います。したがってコピー不可能なラムダ(および他の呼び出し可能ファイル)はstd::functionと一緒に使用できません。この制限の理由は、規格ではstd::functionがコピー可能である必要があります。コピーできないコール可能で初期化されていれば達成できませんでした。

+0

私は 'std :: functionを試しました f = [] {};自動f2 =移動(f)。 f(); 'と' f() 'は' std :: bad_function_call'を投げました。 '' std :: function'は与えられたファンクタをそれ自身に移動することをサポートしていません。それは常にコピーを行います。 ' –

+2

@BenjiMizrahiいいえ、あなたは 'std :: function'オブジェクトを動かすことでファンクタを' std :: function' *に動かすのを混乱させる*前者はできませんが、格納されたファンクタを実際に移動する*)。前者が不可能な理由は、標準では 'std :: function'がコピー可能であることが要求されています。コピーできないファンクタから構築できれば達成できませんでした。 – Angew

関連する問題