c++ - 为什么coroutine_handle的操作符bool销毁后返回true?
问题描述
我是 C++20 协程的新手,很惊讶知道销毁后会coroutine_handle::operator bool
返回?true
示例程序:
#include <coroutine>
#include <iostream>
struct ReturnObject {
struct promise_type {
void return_void() {}
ReturnObject get_return_object() { return {}; }
std::suspend_never initial_suspend() { return {}; }
std::suspend_never final_suspend() noexcept { return {}; }
void unhandled_exception() {}
};
};
struct Awaiter {
std::coroutine_handle<> *hp_;
constexpr bool await_ready() const noexcept { return false; }
void await_suspend(std::coroutine_handle<> h) { *hp_ = h; }
constexpr void await_resume() const noexcept {}
};
ReturnObject
counter(std::coroutine_handle<> *continuation_out)
{
Awaiter a{continuation_out};
for (;;)
co_await a;
}
int main()
{
std::coroutine_handle<> h;
std::cout << "before construction " << (bool)h << '\n';
counter(&h);
std::cout << "after construction " << (bool)h << '\n';
h.destroy();
std::cout << "after destruction " << (bool)h << '\n';
}
https://gcc.godbolt.org/z/a7ehjzhab
它打印
before construction 0
after construction 1
after destruction 1
为什么true
破坏后它仍然返回?所以就不能区分活跃coroutine_handle
的和被破坏的吗?
解决方案
因为协程句柄基本上只是保存一个地址。您几乎可以将其视为“协程视图”,它不拥有协程。destroy
如果协程无法通过标准控制流(例如生成器)正常退出,则存在。operator bool
for astd::coroutine_handle
被定义为等价于return (bool)address();
除非它来自 noop 承诺(在这种情况下它只是true
)。
因此,当您调用时.destroy()
,没有要求(我可以找到)句柄将自身设置为在调用(甚至检查)nullptr
之后对句柄进行任何操作(甚至检查),我可以告诉未定义的行为。destroy
operator bool
所以不可能区分活动的 coroutine_handle 和被破坏的 coroutine_handle 吗?
并不真地?你不是故意的。一旦destroy
被调用,您应该摆脱句柄或重新初始化它(使用nullptr
协程或协程)。
推荐阅读
- python - 为什么(Kivy)下拉菜单不显示?
- c++ - 使用 cmake 将 boost 链接到 c++:命令行编译
- jpa - entityManager.merge(object) 仅保留列表中的最后一条记录
- android - Android 位图到每个像素转换的字节数组
- sql - 事务日志已满
- php - 使用 Eloquent 插入和更新基于多行的外键的最佳方法是什么?
- biztalk - Biztalk 映射循环
- sql - 每次到店购买超过 3 张不同 CD 的客户数量
- react-native - 使用 Apollo 时如何设置 navigationOptions?
- php - 不使用 intdiv() 的整数(64 位)除法(php7 之前)