c++ co_await, co_yield, co_return c++协程关键字详解【核心】

co_await、co_yield、co_return是C++20协程的三大关键字,本质为编译器生成状态机的语法糖,其行为由promise type和awaitable类型共同决定。

这三个关键字是 C++20 协程的核心语法糖,它们本身不实现协程逻辑,而是编译器用来生成状态机代码的“钩子”。真正决定协程行为的是你提供的 promise typeawaitable 类型。

co_await:挂起并等待异步操作完成

它把当前协程暂停,保存执行点(即栈帧局部状态),然后调用 awaitable 对象的 await_ready()await_suspend()await_resume() 三个成员函数。常见用法:

  • 等待一个自定义 awaitable(如 taskstd::experimental::suspend_always
  • 等待标准库中支持协程的 I/O 操作(如 asio::awaitablestd::generator 的迭代)
  • 不能直接 co_await 普通值或函数调用;必须返回满足 awaitable 概念的对象

co_yield:挂起并返回一个值(用于生成器)

本质是 co_await promise.yield_value(value) 的语法糖。它让协程产出一个值后挂起,下次恢复时从下一行继续执行。典型场景是实现惰性序列:

  • 常用于 std::generator 或自定义生成器类型
  • 每次调用 generator.next() 触发一次 co_yield 后的恢复
  • 底层要求 promise type 提供 yield_value(T&&) 成员,并返回一个 awaitable

co_return:结束协程并传递结果或异常

它不是简单地 return;而是触发 promise 的清理和结果传递流程:

  • co_return expr; 等价于 promise.return_value(expr); goto final_suspend;
  • co_return;(无表达式)等价于 promise.return_void(); goto final_suspend;
  • 若协程内抛出异常,编译器自动插入 promise.unhandled_exception();
  • 最终都会进入 promise.final_suspend() 返回的 awaitable,决定是否销毁协程帧

不复杂但容易忽略:没有 promise type,这三个关键字无法编译;没有合适的 awaitable,co_await 就会报错;而 co_yieldco_return 的行为完全由 promise 的对应成员函数定义。