std::coroutine_handle

< cpp‎ | coroutine
 
 
工具库
通用工具
日期和时间
函数对象
格式化库 (C++20)
(C++11)
关系运算符 (C++20 中弃用)
整数比较函数
(C++20)
swap 与类型运算
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
常用词汇类型
(C++11)
(C++17)
(C++17)
(C++17)
(C++17)

初等字符串转换
(C++17)
(C++17)
 
协程支持
协程特征
协程柄
coroutine_handle
(C++20)
无操作协程
平凡可等待体
 
 
定义于头文件 <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 的特化的程序行为未定义。

成员函数

构造 coroutine_handle 对象
(公开成员函数)
(C++20)
赋值 coroutine_handle 对象
(公开成员函数)
[静态] (C++20)
从协程的承诺对象创建 coroutine_handle
(公开静态成员函数)
观察器
(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