c++11异步延续或尝试.then()语义
c++11 async continuations or attempt at .then() semantics
下面的代码是基于Herb Sutter关于.then()类型延续的实现思想。
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()甚至await.)
在让未来共享或类似之前,我想知道堆栈溢出社区会如何看待这个实现,特别是改进和建议(甚至共享未来)?
提前感谢您的建议。
(我知道这是一个修复,直到一个基于标准的机制存在,因为它将花费一个线程(可能)))。
我发现上述实现有3个问题:
- 只有当你将
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;
});
下面是用g++ 4.8和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;
}
相关文章:
- 何时在引用或唯一指针上使用移动语义
- 如何从具有移动语义的类对象中生成共享指针
- Boost Spirit,获取迭代器内部语义动作
- 可以使用移动语义更改或改进此C++代码吗?
- c++在使用指针时移动语义
- 在C++17中,引用const字符串的语义应该是什么
- Xcode 语义问题引用或以前定义的代码
- 使用移动和复制语义时函数匹配如何工作?
- 将向量从 N1 缩小到 N2 项,而不触发默认构造函数并仅使用 move 语义
- 移动语义和深层/浅层复制之间有什么关系?
- 了解构造函数在移动、复制、赋值语义中的行为
- std::unique_lock移动语义
- 移动语义和运算符 + 重载
- C++ 移动语义是否在任何情况下都能节省资源?
- 移动语义在这里如何工作?
- 使用移动语义:右值引用作为方法参数
- 是否可以/希望创建不可复制的共享指针模拟(以启用weak_ptr跟踪/借用类型语义)?
- 在C++中使用移动语义的正确方法是什么?
- C++ 价值语义、不可变性和继承性
- c++11异步延续或尝试.then()语义