下面的代码是基于香草萨特的一个。那么()型延续的执行理念。
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 ++的未来版本(虽然为。那么(),甚至等待。)
使得期货共享或类似之前我不知道什么堆栈溢出社会将专门觉得这个实施与改进及建议(甚至共享期货)?
在此先感谢您的任何建议。
(我知道这是一个修复,直到一个基于标准的机制的存在,因为它会花费一个线程(也许)))。
我发现3个问题与上面的FPGA实现:
- 如果你通过它只会工作
std::shared_future
为Fut
。 - 延续可能想要一个机会来处理异常。
- 它不会总是像预期的那样,因为如果你不指定
std::launch::async
可能被推迟,从而延续不调用正如人们所期望。
我试图解决这些:
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;
});
这里是溶液,用克++ 4.8和铛++ 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;
}