std::generator 在 C++23 中尚未标准化,不存在于任何正式标准库中;它既非标准组件,也非已批准提案,当前所有实现均为实验性或第三方提供。

std::generator 在 C++23 中尚未标准化——它根本不存在于当前任何正式发布的标准库中。
为什么找不到 std::generator?
这是最常被误解的起点。C++23 标准文档里没有 std::generator;它既不是 TS(技术规范),也不是委员会已批准的提案。你在网上看到的实现,基本来自:
- Clang 17+ 的实验性
std::generator(基于std::coroutine_handle+ 自定义 promise_type,非标准) - 第三方库(如 cppcoro 的
cppcoro::generator) - 博客或教程中手写的简化版(通常只支持单线程、无异常传播、不处理 co_await)
所以当你 #include <generator> 报错,或者 std::generator<int> 不识别,不是你配置错了,是标准还没收编它。
替代方案:用 std::coroutine_handle 手写轻量 generator
如果你真需要流式、栈内存友好的迭代器(比如遍历大文件行、生成斐波那契、逐块读取网络响应),可行路径是自己封装协程句柄。关键不是“复刻 Python yield”,而是控制挂起点与内存生命周期:
立即学习“C++免费学习笔记(深入)”;
- 返回值类型必须是可移动的(避免拷贝大对象)
- promise_type 要显式定义
get_return_object()和initial_suspend()(通常设为suspend_always{}) - 每次
co_yield后,外部需调用resume(),且必须检查done()再访问value() - 不要在协程内捕获局部引用或指针——协程可能跨栈帧挂起,局部变量早已析构
示例骨架(省略完整 promise_type 实现):
generator<std::string> read_lines(std::ifstream& f) {
std::string line;
while (std::getline(f, line)) {
co_yield line; // line 被 move 构造进 generator 内部存储
}
}
真实项目中更推荐的“内存友好迭代”做法
别过早陷入协程抽象。多数流式场景下,std::generator 带来的复杂度远超收益,尤其要考虑:
- 调试困难:gdb 对协程栈帧支持弱,
co_yield处断点可能失效 - 异常安全:一旦协程内抛异常且未被捕获,
destroy()可能不被调用,导致资源泄漏 - ABI 不稳定:不同编译器/标准库对协程 ABI 实现有差异,二进制兼容性差
- 替代足够好:用
std::ranges::istream_view<std::string>(C++20)或带状态的 lambda +std::optional<T>返回,更可控
比如逐行读取:
auto lines = std::ranges::istream_view<std::string>(file_stream);
for (const auto& line : lines | std::views::take(100)) { /* ... */ }
协程的价值在于复杂状态机(比如解析嵌套 JSON 流、组合多个异步源),而不是简单“一边生成一边消费”。真要用,先确认团队工具链(clang 版本、调试器、CI 环境)是否真正支持,而不是只看代码能不能编译过。









