Promise对象是协程状态的管家,由编译器自动构造并全程控制协程帧生命周期;其promise_type必须实现get_return_object、initial_suspend、final_suspend和unhandled_exception四个接口,分别负责返回协程对象、启动挂起、结束挂起及异常处理。

Promise 对象是协程状态的“管家”
它不直接执行协程逻辑,而是由编译器在协程函数入口自动构造,全程持有协程帧(coroutine frame)的元信息和生命周期控制权。你定义的 promise_type 类型,就是这个管家的“行为契约”——编译器只认它的接口,不关心内部怎么实现。
必须实现的四个核心接口及其作用
编译器在不同阶段会调用这些函数,缺一不可,否则编译失败:
-
get_return_object():返回协程对外暴露的对象(比如Task),通常包装了coroutine_handle -
initial_suspend():决定协程启动时是否挂起;返回std::suspend_always或std::suspend_never -
final_suspend():决定协程结束时是否挂起;常返回std::suspend_always以防止帧被自动销毁 -
unhandled_exception():捕获协程内未处理的异常,必须显式处理(如保存、重抛或终止)
为什么 final_suspend() 返回 suspend_always 很关键?
协程结束后,若 final_suspend() 返回 std::suspend_never,编译器会自动销毁协程帧(包括 promise 对象)。但多数场景下,你希望手动控制销毁时机(比如等待外部消费者取走结果、或复用帧),这时就必须让协程停在 final 挂起点,靠外部调用 handle.destroy() 显式清理。
常见错误是忘记重载 await_ready() 或 await_resume() 在自定义 awaiter 中,导致 final_suspend() 的挂起行为失效。
立即学习“C++免费学习笔记(深入)”;
Promise 类型如何参与值传递与异常传播?
协程中 co_return expr; 会被编译器转成:
promise.return_value(expr); // 或 promise.return_void()(无返回值时)所以你要在
promise.unhandled_exception(); // 若中途抛异常
promise_type 中提供对应函数,并把值/异常存到 promise 成员里,供后续通过 handle.promise() 访问。
注意:return_value 不负责移动或拷贝 expr,那是你自己的事;如果 expr 是临时对象,又没正确转移,容易出现悬垂引用。
promise_type 的构造/析构和 destroy() 调用时机决定,不是靠作用域或智能指针自动管理——这点和普通对象完全不同,最容易被忽略。











