LoginSignup
10
3

More than 5 years have passed since last update.

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

Posted at

はじめに

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

10
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
3