2012-11-07 4 views
10

の使用結合する方法:AsyncOperation私はこれよりも頻繁ような何かをする必要があるのstdとのstd ::バインド:: shared_ptrの

AsyncOperation * pAsyncOperation = new AsyncOperation(); 
auto bindOperation = std::bind(&AsyncOperation::operator(), std::ref(*pAsyncOperation)); 
std::thread thread(bindOperation); 
thread.join(); 

もファンクタとして知られているoperator()を実装するカスタムクラス(であることをまたは関数オブジェクト)

std::bindstd::refの代わりにstd::shared_ptrを使用することはできますか? pAsyncOperationの参照を保持する必要なくメモリリークを防ぎ、スレッドの最後にAsyncOperationを自動的に削除します。つまり、この非同期タスクが終了します。

編集:私はいつもstd :: threadにアクセスするとは限りません。スレッドライブラリはboost :: threadや他のプラットフォームに依存するスレッドでもあります。結果として、std :: asyncへのアクセスではありません。

私の主な問題は、std :: bindに所有権を持つことです。

+0

あなたは 'のstd :: shared_ptr'を使用しようとしたことがありますか?問題なしでコンパイルしているようです:http://liveworkspace.org/code/1e83d9698703711b7ed2ce0d44cf86f2 – PiotrNycz

+1

あなたが知る必要があるのは、 'std :: bind'はバウンド引数を値渡し(つまり渡された)ポインタを値の1つとして値として渡すと、そのポインタは結果の関数に 'コピー'され、元の 'shared_ptr'が有効範囲外になった後でも所有権を保持します。 – haelix

答えて

10

これは動作します:

struct AsyncOperation { 
    void operator()() 
    { 
     std::cout << "AsyncOperation" << '\n'; 
    } 
}; 

int main() { 
    std::shared_ptr<AsyncOperation> pAsyncOperation = std::make_shared<AsyncOperation>(); 
    auto bindOperation = std::bind(&AsyncOperation::operator(), pAsyncOperation); 
    std::thread thread(bindOperation); 
    thread.join(); 
} 

参照:http://liveworkspace.org/code/4bc81bb6c31ba7b2bdeb79ea0e02bb89

+0

'make_shared'を使う必要がありますか、' std :: shared_ptr pAsyncOperation(new AsyncOperation()); 'do? – akaltar

+1

@akaltarあなたは両方の "スタイル"を使うことができますが、make_sharedはより良いです:https://stackoverflow.com/questions/31232146/why-is-it-better-to-use-stdmake-instead-of-the-コンストラクタ – PiotrNycz

7

AsyncOperationを動的に割り当てる必要がありますか?そうでない場合、私はそれを行うだろう。そうでない場合は

auto f = std::async([]{ AsyncOperation()(); }); 
f.wait(); 

:あなたはもちろんstd::threadを使用することができます

std::unique_ptr<AsyncOperation> op(new AsyncOperation); 
auto f = std::async([&]{ (*op)(); }); 
f.wait(); 

が、それは多くの問題(他のスレッドで、すなわち例外処理)を提供することができます。 std::bindにも独自の問題があり、おそらくラムダで終わるほうがよいでしょう。あなたが本当に他のスレッドに所有権を渡す必要がある場合は

あなたもそれを行うことができます:移動タイプをサポートしていないラムダはまだキャプチャ

std::unique_ptr<AsyncOperation> op(new AsyncOperation); 
auto f = std::async([&](std::unique_ptr<AsyncOperation> op){ (*op)(); }, std::move(op)); 
f.wait(); 

として。

私は役立つことを願っています。

関連する問題