c++11 async continuations or attempt at .then() semantics

前端 未结 2 1676
温柔的废话
温柔的废话 2020-12-13 05:57

The code below is based on Herb Sutter\'s ideas of an implementation of a .then() type continuation.

  template
auto then(F         


        
相关标签:
2条回答
  • 2020-12-13 06:01

    Here is the solution, tested with g++ 4.8 and clang++ 3.2:

    template<typename F, typename W>
    auto then(F&& f, W w) -> std::future<decltype(w(f.get()))>
    {
      cout<<"In thread id = "<<std::this_thread::get_id()<<endl;
      return std::async(std::launch::async, w, f.get());
    }
    
    void test_then()
    {
      std::future<int> result=std::async([]{ return 12;});
      auto f = then(std::move(result), [](int r) {
        cout<<"[after] thread id = "<<std::this_thread::get_id()<<endl;
        cout<<"r = "<<r<<endl;
        return r*r;
      });
      cout<<"Final result f = "<<f.get()<<endl;
    }
    
    0 讨论(0)
  • 2020-12-13 06:18

    I find 3 problems with the above implemention:

    • It will only work if you pass std::shared_future as Fut.
    • The continuation might want a chance to handle exceptions.
    • It will not always behave as expected, since if you do not specify std::launch::async it might be deferred, thus the continuation is not invoked as one would expect.

    I've tried to address these:

    template<typename F, typename W, typename R>
    struct helper
    {
        F f;
        W w;
    
        helper(F f, W w)
            : f(std::move(f))
            , w(std::move(w))
        {
        }
    
        helper(const helper& other)
            : f(other.f)
            , w(other.w)
        {
        }
    
        helper(helper&& other)
            : f(std::move(other.f))
            , w(std::move(other.w))
        {
        }
    
        helper& operator=(helper other)
        {
            f = std::move(other.f);
            w = std::move(other.w);
            return *this;
        }
    
        R operator()()
        {
            f.wait();
            return w(std::move(f)); 
        }
    };
    
    }
    
    template<typename F, typename W>
    auto then(F f, W w) -> std::future<decltype(w(F))>
    { 
        return std::async(std::launch::async, detail::helper<F, W, decltype(w(f))>(std::move(f), std::move(w))); 
    }
    

    Used like this:

    std::future<int> f = foo();
    
    auto f2 = then(std::move(f), [](std::future<int> f)
    {
        return f.get() * 2; 
    });
    
    0 讨论(0)
提交回复
热议问题