实施未来::则(),相当于在C异步执行++ 11 [英] implementing future::then() equivalent for asynchronous execution in c++11
问题描述
我对函数的实现了几个问题,然后()的<一个href=\"http://channel9.msdn.com/Shows/Going+Deep/C-and-Beyond-2012-Herb-Sutter-Concurrency-and-Parallelism\">Herb萨特的谈话。此功能用于连锁异步操作,参数˚F
是一个操作一个未来和参数是W
是作品进行此项操作(拉姆达)。
模板&LT; typename的笏,typename的工作与GT;
然后自动(FON楼工作W) - &GT;未来&LT; decltype(W(f.get()))&GT;
{
返回异步([=] {W(f.get());});
}
应用的一个例子是:
的std ::未来&LT; INT&GT; F =的std ::异步([] {
的std :: this_thread :: sleep_for(性病::时辰::微秒(200));
返回10;
}); 汽车F2 =则(性病::移动(F),[](int i)以{
返回2 * I;
});
在主线程派生的任务,但不等待任何人来完成。
首先,未来&LT; T&GT;
没有一个拷贝构造函数。这意味着,该建议的实施可与 shared_future&LT的前提下使用; T&GT;
除非我们改变异步()调用
未来进入拉姆达。 <一href=\"http://stackoverflow.com/questions/14200678/c11-async-continuations-or-attempt-at-then-semantics/14200861#comment20089049_14200861\">This SO质疑建议这样做的一种方式,但似乎太复杂了。我重新实现的功能,我想知道我的code是否是正确的还是我错过了什么...
其次,被传递到则()
函数可能是无效
,所以我们实际上需要2个未来的实现则()
,对不对?一位期货返回 T
,一个用于期货返回无效
。
最后,应该的体内拉姆达则()
没有return语句,这样我们实际上可以返回值回来?如果没有return语句,然后返回未来&LT;无效&GT;
,对
我试图解决以上几点,这就是我想出了。难道是正确的吗?
模板&LT; typename的T,typename的工作与GT;
汽车则(未来&LT; T&GT; F,工作W) - &GT;未来&LT; decltype(W(f.get()))&GT;
{
返回异步([](未来&LT; T&GT; F,工作W)
{返回W(f.get()); },移动(F),移动(W));
}模板&LT; typename的工作与GT;
汽车则(未来&LT;无效&GT; F,工作W) - &GT;未来&LT; decltype(W())&GT;
{
返回异步([](未来&LT;无效&GT; F,工作W)
{f.wait();返回W(); },移动(F),移动(W));
}
为了简化界面,我就隐藏无效
实施内部问题,同样什么香草与他的并发&LT做; T&GT;
的实施。相反,具有2 然后
的实施,宣告一个辅助函数 get_work_done
2个实现:
模板&LT; typename的T,typename的工作与GT;
汽车get_work_done(未来&LT; T&GT;&安培; F,工作和放大器; W) - &GT; decltype(W(f.get()))
{返回W(f.get());}模板&LT; typename的工作与GT;
汽车get_work_done(未来&LT;无效&GT;&安培; F,工作和放大器; W) - &GT; decltype(W())
{f.wait();返回W();}
然后让模板参数检测照顾其余的:
模板&LT; typename的T,typename的工作与GT;
汽车则(未来&LT; T&GT; F,工作W) - &GT;未来&LT; decltype(W(f.get()))&GT;
{
返回异步([](未来&LT; T&GT; F,工作W)
{返回get_work_done(F,W); },移动(F),移动(W));
}
I have a few questions about the implementation of the function then() in Herb Sutter's talk. This function is used to chain asynchronous operations, the parameter f
is a future from one operation and the parameter w
is the 'work' for this operation (lambda).
template <typename Fut, typename Work>
auto then(Fut f, Work w) -> future<decltype(w(f.get()))>
{
return async([=]{ w(f.get()); });
}
An example of application would be:
std::future<int> f = std::async([]{
std::this_thread::sleep_for(std::chrono::microseconds(200));
return 10;
});
auto f2 = then(std::move(f), [](int i){
return 2 * i;
});
The main thread spawns the tasks but does not wait for any of them to finish.
Firstly, future<T>
does not have a copy constructor. This means, that the suggested implementation can be only used with shared_future<T>
unless we change the call to async()
to move the future into the lambda. This SO question suggested a way of doing it but it seems too complicated. I re-implemented the function and I am wondering whether my code is correct or whether I missed something...
Secondly, the future that is passed to the then()
function might be void
so we actually need 2 implementations of then()
, right? One for futures returning T
and one for futures returning void
.
Lastly, should the lambda inside the body of then()
not have a return statement so that we can actually return the value back? Without the return statement, then returns future<void>
, right?
I tried to address the above points and this is what I came up with. Is it correct?
template <typename T, typename Work>
auto then(future<T> f, Work w) -> future<decltype(w(f.get()))>
{
return async([](future<T> f, Work w)
{ return w(f.get()); }, move(f), move(w));
}
template <typename Work>
auto then(future<void> f, Work w) -> future<decltype(w())>
{
return async([](future<void> f, Work w)
{ f.wait(); return w(); }, move(f), move(w));
}
In order to simplify the interface, I would "hide" the void
problem inside the implementation, similarly to what Herb did with his concurrent<T>
implementation. Instead of having 2 then
implementations, declare a helper function get_work_done
with 2 implementations:
template <typename T, typename Work>
auto get_work_done(future<T> &f, Work &w)-> decltype(w(f.get()))
{return w(f.get());}
template <typename Work>
auto get_work_done(future<void> &f, Work &w)-> decltype(w())
{f.wait(); return w();}
And then let template parameter detection take care of the rest:
template <typename T, typename Work>
auto then(future<T> f, Work w) -> future<decltype(w(f.get()))>
{
return async([](future<T> f, Work w)
{ return get_work_done(f,w); }, move(f), move(w));
}
这篇关于实施未来::则(),相当于在C异步执行++ 11的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!