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

 ̄綄美尐妖づ 提交于 2019-11-28 17:18:54

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; 
});

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;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!