C++协程能否用普通函数包装并支持co_await?合法性验证
普通函数返回协程可等待对象并被co_await的合法性分析
你的选项A是完全合法且正确的,caller中的co_await wrapper()也完全有效,不存在遗漏问题。
核心原理
co_await的本质是操作一个可等待对象(awaitable),只要该对象满足C++20协程的可等待要求(即提供await_ready、await_suspend、await_resume成员函数,或通过扩展点实现这些逻辑),不管这个对象是来自协程调用还是普通函数返回,都可以被co_await。
在你的示例中:
my_coroutine是协程函数,调用它会直接生成并返回awaitable<int>类型的对象(这是C++20协程的特性:协程函数的返回值由其promise类型生成,本身就是可等待对象)。wrapper作为普通函数,只是把my_coroutine(77)返回的可等待对象直接传递出去,相当于替调用者完成了参数绑定,co_await wrapper()和直接co_await my_coroutine(77)的行为完全一致。
对比选项B
选项B将wrapper也声明为协程是完全不必要的:
co_return co_await my_coroutine(77)会让wrapper额外经历一次协程的挂起与恢复流程,没有任何业务逻辑上的价值,反而会增加少量协程调度的开销,效率不如选项A。
结合Boost ASIO场景的补充
你用lambda作为包装器绑定参数并调用目标协程的写法,和示例中的选项A逻辑一致,完全适配Boost ASIO的awaitable体系:
- ASIO的
awaitable类型本身就符合C++20协程的可等待要求,lambda作为普通函数直接返回目标协程的awaitable对象,不会有任何问题。 - 只要保证lambda返回的是合法的
awaitable值(而非悬空引用),这种参数绑定的写法就是安全高效的。
内容的提问来源于stack exchange,提问作者marack
相关产品推荐
相关产品推荐

