std::coroutine_handle
来自cppreference.com
定义于头文件 <coroutine>
|
||
template< class Promise = void > struct coroutine_handle; |
(1) | (C++20 起) |
template<> struct coroutine_handle<void>; |
(2) | (C++20 起) |
template<> struct coroutine_handle<std::noop_coroutine_promise>; |
(3) | (C++20 起) |
using noop_coroutine_handle = std::coroutine_handle<std::noop_coroutine_promise>; |
(4) | (C++20 起) |
类模板 coroutine_handle
能用于指代暂停或执行的协程。 coroutine_handle
的每个特化均为字面类型 (LiteralType) 。
1) 主模板,可从
Promise
类型的承诺对象创建。2) 特化 std::coroutine_handle<void> 是其他特化的公开基类。它保有协程柄的底层地址。
3) 特化 std::coroutine_handle<std::noop_coroutine_promise> 指代无操作协程。不能从承诺对象创建它。
典型实现上, std::coroutine_handle<> 保有一个指向协程状态的指针作为其仅有的非静态成员,而其他特化不添加任何非静态数据成员,从而所有特化均为可平凡复制 (TriviallyCopyable) 。
添加 coroutine_handle
的特化的程序行为未定义。
成员函数
(C++20) |
构造 coroutine_handle 对象 (公开成员函数) |
(C++20) |
赋值 coroutine_handle 对象 (公开成员函数) |
[静态] (C++20) |
从协程的承诺对象创建 coroutine_handle (公开静态成员函数) |
观察器 | |
(C++20) |
检查协程是否已完成 (公开成员函数) |
(C++20) |
检查柄是否表示协程 (公开成员函数) |
控制 | |
(C++20) |
恢复协程执行 (公开成员函数) |
(C++20) |
销毁协程 (公开成员函数) |
承诺访问 | |
(C++20) |
访问协程的承诺对象 (公开成员函数) |
导出/导入 | |
(C++20) |
导出底层地址,即支撑协程的指针 (公开成员函数) |
[静态] (C++20) |
从指针导入协程 (公开静态成员函数) |
非成员函数
(C++20) |
比较二个 coroutine_handle 对象 (函数) |
辅助类
std::coroutine_handle 的散列支持 (类模板特化) |
注解
coroutine_handle
可能悬垂或(对于 std::coroutine_handle<> 以外的特化)指代承诺类型不是 Promise
的协程,该情况下必须谨慎使用该 coroutine_handle
以避免未定义行为。
示例
运行此代码
#include <coroutine> #include <iostream> #include <ranges> template<class T> struct generator { struct promise_type { auto get_return_object() { return generator(std::coroutine_handle<promise_type>::from_promise(*this)); } std::suspend_always initial_suspend() { return {}; } std::suspend_always final_suspend() noexcept { return {}; } void unhandled_exception() { throw; } std::suspend_always yield_value(T value) { current_value = std::move(value); return {}; } void await_transform() = delete; // 生成器协程中不允许 co_await T current_value; }; generator(std::coroutine_handle<promise_type> h) : coro(h) {} generator(generator&& other) : coro(other.coro) { other.coro = {}; } ~generator() { if (coro) coro.destroy(); } // 基于范围的支持 struct iter { explicit iter(std::coroutine_handle<promise_type> h) : coro(h) {} void operator++() { coro.resume(); } T operator*() const { return coro.promise().current_value; } bool operator==(std::default_sentinel_t) const { return coro.done(); } private: std::coroutine_handle<promise_type> coro; }; iter begin() { return coro.resume(); iter(coro); } std::default_sentinel_t end() { return {}; } private: std::coroutine_handle<promise_type> coro; }; generator<int> ints(int x) { for (int i = 0; i < x; ++i) co_yield i; } int main() { for (auto i : ints(5)) std::cout << i << '\n'; }
输出:
0 1 2 3 4