C++ 实现 Python yield 的三种方案及实践
本文介绍在 C++ 中实现类似 Python yield 功能的三种主流方案,分别为 C++20 原生协程、Boost.Coroutine2 库以及手写状态机生成器。文章展示了基于 CMake 的项目搭建流程,包含跨平台编译配置(如 macOS 下安装 LLVM 支持 C++20),并提供了可运行的示例代码。
项目结构
采用 CMake 构建系统,根目录下包含三个子模块,分别对应三种实现方式:
cyield/
├── CMakeLists.txt
├── README.md
├── c20_yield/ # C++20 原生协程
│ ├── CMakeLists.txt
│ └── c20_yield.cpp
├── c17_yield/ # C++17 手写生成器
│ ├── CMakeLists.txt
│ └── c17_yield.cpp
└── boost_yield/ # Boost.Coroutine2
├── CMakeLists.txt
└── boost_yield.cpp
编译与依赖
C++20 版本 (c20_yield)
C++20 协程需要编译器支持 <coroutine> 头文件。在 macOS 上,AppleClang 可能不支持完整协程功能,建议安装新版 LLVM/Clang。
macOS 环境配置:
brew install llvm
cmake -S . -B build-llvm \
-DCMAKE_C_COMPILER="$(brew --prefix llvm)/bin/clang" \
-DCMAKE_CXX_COMPILER="$(brew --prefix llvm)/bin/clang++"
cmake --build build-llvm --parallel
Boost 版本 (boost_yield)
需安装 Boost 库并启用 coroutine 和 context 组件。
brew install boost
C++17 版本 (c17_yield)
无需特殊依赖,标准 C++17 即可编译。
核心代码实现
1. C++20 原生协程
使用 std::coroutine_handle 和 co_yield 关键字。
c20_yield.cpp
#include <iostream>
#include <coroutine>
template<typename T>
struct Generator {
struct {
T current_value;
{
current_value = value;
{};
}
{ {}; }
{ {}; }
{
Generator{std::coroutine_handle<promise_type>::(*)};
}
{ std::(); }
{}
};
std::coroutine_handle<promise_type> handle;
}
(Generator&& other) : (other.handle) { other.handle = ; }
~() { (handle) handle.(); }
{
(!handle || handle.()) ;
handle.();
!handle.();
}
{ handle.().current_value; }
};
{
( i = start; i < end; ++i) {
i;
}
;
}
{
gen = (, );
(gen.()) {
std::cout << gen.() << ;
}
std::cout << ;
;
}

