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