如何解决为什么 coroutine_handle 的 operator 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
和销毁的 {{1}} 吗?
解决方法
因为协程句柄基本上只保存一个地址。您几乎可以将其视为“协程视图”,它不拥有协程。 destroy
exists if the coroutine wouldn't exit normally 通过标准控制流,例如发电机。 operator bool
的 std::coroutine_handle
被定义为等价于 return (bool)address();
,除非它来自 noop 承诺(在这种情况下它只是 true
)。
因此,当您调用 .destroy()
时,没有要求(我可以找到)将句柄设置回 nullptr
,就像在调用 destroy
之后对句柄执行任何操作一样(即使检查 operator bool
) 也是我能分辨出未定义行为的最佳方法。
因此无法区分活动的 coroutine_handle 和已破坏的 coroutine_handle 吗?
不是吗?你不是故意的。调用 destroy
后,您应该删除句柄或重新初始化它(使用 nullptr
或协程)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。