为什么 coroutine_handle 的运算符 bool return 在销毁后为真?
Why does coroutine_handle's operator bool return true after destruction?
我是 C++20 协同程序的新手,很惊讶地知道 coroutine_handle::operator bool
returns 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
为什么销毁后还是returntrue
?所以无法区分活动的 coroutine_handle
和破坏的?
因为协程句柄基本上只是持有一个地址。你几乎可以认为它是一个“协程视图”,它不拥有协程。 via standard control flow e.g. generators. operator bool
for a std::coroutine_handle
is defined as being equivalent to return (bool)address();
除非它来自 noop promise(在这种情况下它只是 true
)。
因此,当您调用 .destroy()
时,没有要求(我可以找到)句柄将自己设置回 nullptr
,因为在调用 destroy
(甚至检查 operator bool
)是我所能分辨的最好的未定义行为。
So it is not possible to distinguish active coroutine_handle from destructed one?
不是真的?你不是故意的。一旦 destroy
被调用,您应该摆脱句柄或重新初始化它(使用 nullptr
或协程)。
我是 C++20 协同程序的新手,很惊讶地知道 coroutine_handle::operator bool
returns 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
为什么销毁后还是returntrue
?所以无法区分活动的 coroutine_handle
和破坏的?
因为协程句柄基本上只是持有一个地址。你几乎可以认为它是一个“协程视图”,它不拥有协程。 operator bool
for a std::coroutine_handle
is defined as being equivalent to return (bool)address();
除非它来自 noop promise(在这种情况下它只是 true
)。
因此,当您调用 .destroy()
时,没有要求(我可以找到)句柄将自己设置回 nullptr
,因为在调用 destroy
(甚至检查 operator bool
)是我所能分辨的最好的未定义行为。
So it is not possible to distinguish active coroutine_handle from destructed one?
不是真的?你不是故意的。一旦 destroy
被调用,您应该摆脱句柄或重新初始化它(使用 nullptr
或协程)。