C++
JavaScript

JSのPromiseが気持ちがいいのでC++でもやりたい

はじめに

最近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;
}

参考

https://stackoverflow.com/questions/14489935/implementing-futurethen-equivalent-for-asynchronous-execution-in-c11

おまけ

std::futureにthenを追加する提案はでてるようです
https://faithandbrave.hateblo.jp/entry/2014/01/22/170813
http://en.cppreference.com/w/cpp/experimental/future