2017-01-09 11 views
1

への参照を取得し、私はこれに似た署名で(私がコントロールしていないライブラリからではない鉱山、)関数を使用しています:ラムダのキャプチャ値

template<typename T, typename F> 
void do_async(T const&, F); // the second parameter is a callable 

、それは通常、この

のように使用
do_async(obj, [this](){ ... }); 

私はいつも同じコールバックラムダを使用してこれと同様の機能を書きました:私の問題は、FR幹

template<typename T> 
void do_async_wrapper(T obj) { 
    do_async(obj, [this](){ ... }); 
} 

をobjが参照として渡されるので、コールバックが呼び出されるまで、objが生きていなければならないという事実。私の関数はそれを処理することになっているので、呼び出し元はオブジェクトの寿命について心配する必要はありません。それが価値を受け入れる理由です。
私は生きている、それを維持するために、このような何かをしたいと思います:

明らか
template<typename T> 
void do_async_wrapper(T obj) { 
    do_async(obj, [this, obj{std::move(obj)}](){ ... }); 
} 

この文句を言わない(常に)仕事はもう存在しない関数のローカル1を参照点ので、そのまま生きているものは(移動)コピーです。

提案がありますか?

+0

'そのパラメータでやってdo_async'は何?あなたはそれが内部的にコピーを作っていないと確信していますか? – TartanLlama

+0

@TartanLlamaはい。ライブラリのドキュメントでは、オブジェクトが確実に生きていることを確認するのは呼び出し元の責任であると指定しています。 – baruch

+0

ドキュメントにリンクできますか? 1つのオプションは 'std :: shared_ptr'です。 – TartanLlama

答えて

2

ファンクタは価値があるため、ファンクタに直接オブジェクトを格納して参照を渡すことはできません。 あなたが仕事アラウンドことshared_ptrとしてスマートポインタを使用することにより:

template<typename T> 
void do_async_wrapper(T obj) { 
    auto ptr = std::make_shared<T>(std::move(obj)); 
    do_async(*ptr, [this, ptr](){ /*...*/ }); 
} 
+0

'do_async'はラムダをコピーするべきではないので、私は' make_unique'の代わりに 'make_unared'に誘惑されるでしょう。しかし、それはそれを動作させるために余分な行を必要とします( 'auto&obj_ref = * ptr;')。 – Yakk

+0

@ Yakk私はmake_uniqueを使って同様のソリューションを使いました。私はあなたが見せてくれるラインは必要ありませんでした。それのポイントは何ですか? – baruch

+0

@baruch: '* ptr'と' [ptr = std :: move(ptr)] 'の間の不特定の順序と' do_async'の 'F'のコピーの2つの問題があります。 'T'は違う)。 – Jarod42

関連する問題