std::coroutine_handle, std::noop_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) 。
如果程序添加了 std::coroutine_handle
的特化,那么行为未定义。
目录 |
[编辑]数据成员
成员名 | 定义 |
ptr (private) | 指向协程状态的 void* 指针。 (仅用于阐述的成员对象*) |
[编辑]成员函数
构造 coroutine_handle 对象 (公开成员函数) | |
赋值 coroutine_handle 对象 (公开成员函数) | |
转换 | |
获得擦除类型的 coroutine_handle (公开成员函数) | |
观察器 | |
检查协程是否已完成 (公开成员函数) | |
检查柄是否表示协程 (公开成员函数) | |
控制 | |
恢复协程执行 (公开成员函数) | |
销毁协程 (公开成员函数) | |
承诺访问 | |
访问协程的承诺对象 (公开成员函数) | |
[静态] | 从协程的承诺对象创建 coroutine_handle (公开静态成员函数) |
导出/导入 | |
导出底层地址,即指代协程的指针 (公开成员函数) | |
[静态] | 从指针导入协程 (公开静态成员函数) |
[编辑]非成员函数
(C++20) | 比较两个 coroutine_handle 对象 (函数) |
[编辑]辅助类
std::coroutine_handle 的散列支持 (类模板特化) |
[编辑]注解
coroutine_handle
可能悬垂,该情况下必须谨慎使用该 coroutine_handle
以避免未定义行为。
[编辑]示例
运行此代码
#include <coroutine>#include <iostream>#include <optional> template<std::movable T>class Generator {public:struct promise_type { Generator<T> get_return_object(){return Generator{Handle::from_promise(*this)};}staticstd::suspend_always initial_suspend()noexcept{return{};}staticstd::suspend_always final_suspend()noexcept{return{};}std::suspend_always yield_value(T value)noexcept{ current_value = std::move(value);return{};}// 生成器协程中不允许 co_await。void await_transform()= delete;[[noreturn]]staticvoid unhandled_exception(){throw;} std::optional<T> current_value;}; using Handle = std::coroutine_handle<promise_type>; explicit Generator(const Handle coroutine): m_coroutine{coroutine}{} Generator()=default; ~Generator(){if(m_coroutine) m_coroutine.destroy();} Generator(const Generator&)= delete; Generator& operator=(const Generator&)= delete; Generator(Generator&& other)noexcept: m_coroutine{other.m_coroutine}{ other.m_coroutine={};} Generator& operator=(Generator&& other)noexcept{if(this !=&other){if(m_coroutine) m_coroutine.destroy(); m_coroutine = other.m_coroutine; other.m_coroutine={};}return*this;} // 基于范围的 for 循环支持。class Iter {public:void operator++(){ m_coroutine.resume();}const T& operator*()const{return*m_coroutine.promise().current_value;}bool operator==(std::default_sentinel_t)const{return!m_coroutine || m_coroutine.done();} explicit Iter(const Handle coroutine): m_coroutine{coroutine}{} private: Handle m_coroutine;}; Iter begin(){if(m_coroutine) m_coroutine.resume();return Iter{m_coroutine};} std::default_sentinel_t end(){return{};} private: Handle m_coroutine;}; template<std::integral T> Generator<T> range(T first, const T last){while(first < last) co_yield first++;} int main(){for(constchar i : range(65, 91))std::cout<< i <<' ';std::cout<<'\n';}
输出:
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
[编辑]缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
缺陷报告 | 应用于 | 出版时的行为 | 正确行为 |
---|---|---|---|
LWG 3460 | C++20 | coroutine_handle 的公开基类能将它置于不想要的状态 | 移除继承 |
[编辑]参阅
(C++23) | 表示同步协程生成器的 view (类模板) |