c ++ 11异步继续或尝试.then()语义 [英] c++11 async continuations or attempt at .then() semantics

查看:135
本文介绍了c ++ 11异步继续或尝试.then()语义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码基于草药Sutter的一个实现.then()类型延续的想法。

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

  template<typename Fut, typename Work>
auto then(Fut f, Work w)->std::future<decltype(w(f.get()))>
  { return std::async([=] { w(f.get()); }); }

这将像 auto next = then(f, (int r){go_and_use(r);}); 或类似。

这是一个整洁的想法,但它不会工作(期货是移动,不可复制)。我真的很喜欢这个想法,因为它可能出现在即将到来的版本的c ++中,尽管我可以猜到(虽然作为.then()或甚至等待。)

This is a neat idea, but as it stands will not work (futures are move only and not copyable). I do like the idea as it is likely to appear in upcoming versions of c++ as far as I can guess (although as .then() or even await.)

使期货共享或类似我不知道堆栈溢出社区会想到这个实现具体改进和建议(甚至共享期货)?

Before making the futures shared or similar I wonder what the stack overflow community would think of this implementation specifically with improvements and suggestions (even shared futures)?

感谢您提出任何建议。

(我知道这是一个修正,直到基于标准的机制

(I am aware this is a fix till a standards based mechanism exists as it will cost a thread (maybe))).

推荐答案

我发现上面实现的3个问题:

I find 3 problems with the above implemention:


  • 只有在 std :: shared_future


  • 继续可能希望有机会处理例外。如果你没有指定 std :: launch :: async ,它可能被延迟,因此延续不会按照预期的方式被调用。

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

使用像这样:

std::future<int> f = foo();

auto f2 = then(std::move(f), [](std::future<int> f)
{
    return f.get() * 2; 
});

这篇关于c ++ 11异步继续或尝试.then()语义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆