C++23 标准中不存在 std::generator,它从未被纳入 ISO 标准;实际可用的是用户自定义协程返回类型,需手动实现 promise_type 及迭代器接口,或选用 cppcoro、libunifex 等第三方库。

std::generator 在 C++23 中并不存在 —— 这是常见误解。标准库目前(截至 C++23 最终草案及 GCC 14 / Clang 18 实现)**没有提供 std::generator 类型**。
为什么搜不到 std::generator?
它从未被纳入 ISO C++23 标准。你可能看到的是以下几种情况:
- 某些博客或教程把实验性实现(如 LLVM 的
libc++协程提案原型)误称为“C++23 特性” - 混淆了 C++20 协程核心机制(
co_await/co_yield/co_return)与“生成器类库”的区别 - 参考了第三方库(如
range-v3的generator、或cppcoro的generator)
C++20 协程怎么写出类似生成器的行为?
真正可用的是「用户自定义协程返回类型」,需手动实现一个满足 promise_type 要求的生成器类。典型结构包括:
- 返回类型(如
generator)必须定义嵌套promise_type -
promise_type::get_return_object()返回自身实例 -
promise_type::yield_value(T&&)存值并挂起 - 需配合
iterator接口(begin()/end())才能用于 range-for
例如最小可行生成器(GCC 13+ / Clang 16+ 启用 -std=c++20 -fcoroutines):
立即学习“C++免费学习笔记(深入)”;
struct generator {
struct promise_type {
int current_value;
generator get_return_object() { return generator{handle_type::from_promise(*this)}; }
std::suspend_always initial_suspend() { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void unhandled_exception() { std::terminate(); }
std::suspend_always yield_value(int v) { current_value = v; return {}; }
void return_void() {}
};
using handle_type = std::coroutine_handle;
handle_type h_;
explicit generator(handle_type h) : h_(h) {}
~generator() { if (h_) h_.destroy(); }
struct iterator {
handle_type h_;
int operator*() const { return h_.promise().current_value; }
iterator& operator++() { h_.resume(); return *this; }
bool operator!=(const iterator&) const { return !h_.done(); }
};
iterator begin() { if (h_) h_.resume(); return iterator{h_}; }
iterator end() { return iterator{nullptr}; }
};
用法:
generator fib() {
int a = 0, b = 1;
co_yield a;
co_yield b;
while (true) {
co_yield a + b;
auto next = a + b;
a = b; b = next;
}
}
for (int x : fib()) { / ... / } // 注意:无限序列需手动 break
实际开发中该用哪个“generator”?
别自己从头写。推荐直接使用成熟协程库:
-
cppcoro(Microsoft 开源):提供cppcoro::generator,支持co_yield、range-for、移动语义 -
libunifex(Facebook/Folly):更侧重异步流,但含generator概念的适配器 -
range-v3:虽无协程版生成器,但其view::generate可模拟无状态惰性序列
注意:cppcoro::generator 不是标准组件,需额外链接,且其 begin() 会触发首次 resume —— 若协程抛异常,将传播到迭代器构造时,这点容易被忽略。
真正要注意的不是“怎么用 std::generator”,而是:协程生成器必然携带状态(栈帧、局部变量、挂起点),所谓“无状态”只存在于生成逻辑不捕获任何变量的极简场景;一旦用了 co_yield 带出局部值,状态就隐式存在了。










