为什么 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 或协程)。