32

Herb Sutter の講演then()で関数の実装についていくつか質問があります。この関数は、非同期操作をチェーンするために使用されます。パラメーターは 1 つの操作からの未来であり、パラメーターはこの操作の「作業」(ラムダ) です。fw

template <typename Fut, typename Work>
auto then(Fut f, Work w) -> future<decltype(w(f.get()))>
{
    return async([=]{ w(f.get()); });
}

アプリケーションの例は次のとおりです。

    std::future<int> f = std::async([]{
        std::this_thread::sleep_for(std::chrono::microseconds(200));
        return 10;
    });

    auto f2 = then(std::move(f), [](int i){
        return 2 * i;
    });

メイン スレッドはタスクを生成しますが、それらのいずれかが終了するのを待ちません。

まず、future<T>コピー コンストラクターがありません。これは、未来をラムダに移動するためにshared_future<T>呼び出しを変更しない限り、提案された実装はでのみ使用できることを意味します。This SO questionはそれを行う方法を提案しましたが、複雑すぎるようです。関数を再実装しましたが、コードが正しいかどうか、または何かを見逃しているかどうか疑問に思っています...async()

第 2 に、then()関数に渡される未来は である可能性があるvoidため、実際には の 2 つの実装が必要then()ですよね? 1 つは先物返品用T、もう 1 つは先物返品用voidです。

then()最後に、実際に値を返すことができるように、本体内のラムダにreturn ステートメントを含めないでください。return ステートメントがなければ、 returnfuture<void>ですね。

上記の点に対処しようとしましたが、これが私が思いついたものです。それが正しいか?

template <typename T, typename Work>
auto then(future<T> f, Work w) -> future<decltype(w(f.get()))>
{
    return async([](future<T> f, Work w)
                      { return w(f.get()); }, move(f), move(w));
}

template <typename Work>
auto then(future<void> f, Work w) -> future<decltype(w())>
{
    return async([](future<void> f, Work w)
                      { f.wait(); return w(); }, move(f), move(w));
}
4

3 に答える 3

4

voidインターフェイスを単純化するために、Herb が実装で行ったのと同様に、問題を実装内に「隠す」ことにしましたconcurrent<T>。2 つの実装を持つ代わりに、2 つのthen実装を持つヘルパー関数を宣言しget_work_doneます。

template <typename T, typename Work>
auto get_work_done(future<T> &f, Work &w)-> decltype(w(f.get()))
{return w(f.get());}

template <typename Work>
auto get_work_done(future<void> &f, Work &w)-> decltype(w())
{f.wait(); return w();}

あとはテンプレート パラメータの検出に任せます。

template <typename T, typename Work>
auto then(future<T> f, Work w) -> future<decltype(w(f.get()))>
{
    return async([](future<T> f, Work w)
                      { return get_work_done(f,w); }, move(f), move(w));
}
于 2013-02-18T11:54:35.560 に答える