はじめに
最近JSを書いているんですが、非同期処理をPromiseでメソッドチェーンをしていくのが気持ちがいいです。
参考:Promiseと仲良くなって気持ち良く非同期処理を書こう
C++でもやってみたかったので簡単な実装だけしてみました
実装方針
operatorオーバーロードによる、なんちゃってメソッドチェーンで実装します。
C++にも統一関数呼び出し構文が欲しい
実装
future_then.hpp
//std::future.then風 関数オブジェクト
constexpr struct FutureThen_OP
{
private:
template<class Func>
struct Param
{
Func func;
};
public:
//thenの引数うけとり
template<class Func>
Param<Func> operator ()(Func f)const
{
return { std::move(f) };
}
//thenの実装
template<class T,class Func>
friend auto operator | (std::future<T> fut, Param<Func> param)->std::future<decltype(param.func(fut.get()))>
{
return std::async([](std::future<T> fut, Func func)
{
return func(fut.get());
}, std::move(fut), std::move(param.func));
}
//thenの実装 future<void>用
template <class Func>
friend auto operator | (std::future<void> fut, Param<Func> param)->std::future<decltype(param.func())>
{
return std::async([](std::future<void> fut, Func func)
{
fut.wait();
return func();
}, std::move(fut), std::move(param.func));
}
}then;
使い方
operator | でチェーンして使います
main.cpp
int main()
{
auto f = std::async([]{
return 10;
})| then([](int i){
std::cout << i;
return 2 * i;
})| then([](int i) {
std::cout << i;
return 3 * i;
})| then([](int i) {
std::cout << i;
return 4 * i;
});
std::cout<< f.get();
return 0;
}
参考
おまけ
std::futureにthenを追加する提案はでてるようです
https://faithandbrave.hateblo.jp/entry/2014/01/22/170813
http://en.cppreference.com/w/cpp/experimental/future