自从在Kona的ISO会议上,协同程序TS已经被接受并纳入了C++20标准,我开始对它们进行一些尝试。Clang已经具有相当不错的协程支持,但库支持的实现仍然缺少。特别是像std::future、std::generator等类型尚未实现。
因此,我决定让std::future可等待。我主要参考了James McNellis在CppCon 2016的演讲,特别是这张幻灯片:talk by James McNellis at CppCon 2016。
既然现在已经是2019年,我遇到了这个幻灯片上的(假设未经测试的?)代码有些麻烦:
- 我觉得重载
operator co_await
已经不再可行?而应该使用promise_type
的可选await_transform
。不过我也不能确定自己理解的是否正确。 future
的then
继续通过值捕获句柄,但是resume
成员函数没有被声明为const。我通过使lambda表达式mutable
来解决这个问题。
此外,then
和is_ready
都不适用于std::future
,而是std::experimental::future
的一部分,但我的libc++版本中仍然缺失。为了避免处理Awaiter并实现future continuations,我编写了一个派生的future类,它既是Awaitable又是Awaiter。我认为最终std::future
也将是如此。你可以在Compiler Explorer上查看我的示例。这个代码可以编译。
get()
时,await_resume
会发生段错误。这实际上并不奇怪,因为此时valid()
返回false
(使调用get()
成为未定义行为)。我认为这是因为当then
用于继续future时,原始future对象被移动到异步future中,从而使旧future无效(在调用await_resume
时的*this
,所以在移动后)。我的then
实现受此答案和此代码的启发,我在GitHub上找到了这些内容。它们可能不是理想的,但cppreference明确说明调用then
的后置条件是valid() == false
,因此我认为从原始future中移出是正确的。
我错过了什么?这个“bug”似乎已经存在于上面的幻灯片中。如何解决这个问题?有没有人知道一个(可行的)现有的Awaitable future实现?谢谢。
std::future
可等待的。 - anton_rh