C++20通过协程实现生成器,利用co_yield暂停函数并返回值,配合promise_type和coroutine_handle管理状态,可构建如斐波那契数列的惰性序列,支持类似Python生成器的惰性求值行为。

C++20 引入了协程(Coroutines)支持,使得我们可以用 co_yield 实现类似 Python 中的生成器(Generator)。通过协程,函数可以暂停执行并返回一个值,之后从中断处继续运行。这种机制非常适合实现惰性求值的序列,也就是“生成器”。
1. 生成器的基本结构
要实现一个生成器,我们需要定义一个返回类型,该类型满足协程的接口要求,通常包括 promise_type、get_return_object、initial_suspend、final_suspend 和 unhandled_exception 等组件。
下面是一个简单的整数生成器示例:
#include #include struct Generator { struct promise_type { int current_value; // 返回生成器对象 Generator get_return_object() { return Generator{std::coroutine_handle::from_promise(*this)}; } // 协程开始时是否挂起 std::suspend_always initial_suspend() { return {}; } // 协程结束时是否挂起 std::suspend_always final_suspend() noexcept { return {}; } // 每次 co_yield 后挂起 std::suspend_always yield_value(int value) { current_value = value; return {}; } void return_void() {} void unhandled_exception() { std::terminate(); } }; using handle_type = std::coroutine_handle; explicit Generator(handle_type h) : coro(h) {} ~Generator() { if (coro) coro.destroy(); } // 移动构造和赋值 Generator(Generator&& other) noexcept : coro(other.coro) { other.coro = nullptr; } Generator& operator=(Generator&& other) noexcept { if (this != &other) { if (coro) coro.destroy(); coro = other.coro; other.coro = nullptr; } return *this; } // 删除拷贝操作 Generator(const Generator&) = delete; Generator& operator=(const Generator&) = delete; // 检查是否还有值 bool next() { if (!coro || coro.done()) return false; coro.resume(); return !coro.done(); } // 获取当前值 int value() const { return coro.promise().current_value; }private: handle_type coro;};
2. 使用 co_yield 定义生成函数
有了上面的 Generator 类型后,就可以写一个使用 co_yield 的函数来生成一系列值。
立即学习“C++免费学习笔记(深入)”;
Generator fibonacci() { int a = 0, b = 1; while (true) { co_yield a; int tmp = a + b; a = b; b = tmp; }}
这个函数会无限生成斐波那契数列中的每一项。每次调用 co_yield 时,函数会保存状态并返回当前值,下次从下一条语句继续执行。
3. 遍历生成器的值
使用前面定义的 Generator,我们可以像这样遍历前几个斐波那契数:
int main() { auto gen = fibonacci(); for (int i = 0; i < 10 && gen.next(); ++i) { std::cout << gen.value() << " "; } std::cout << std::endl; return 0;}
输出结果:
0 1 1 2 3 5 8 13 21 34
4. 关键点说明
co_yield 表达式:将值传给生成器,并挂起协程。下次恢复时从它后面继续执行。std::suspend_always / std::suspend_never:控制协程在启动或结束时是否挂起。一般 initial_suspend 用 suspend_always 可以延迟执行,直到第一次 resume。promise_type 是核心,它决定了协程的行为。协程句柄(coroutine_handle) 允许外部控制协程的生命周期和执行流程。
基本上就这些。C++ 的协程比 Python 更底层,需要手动管理一些细节,但灵活性更高。一旦封装好 Generator 类,使用起来就很接近传统意义上的生成器了。
以上就是c++++如何利用协程实现一个生成器(Generator)_c++ co_yield的使用的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1487809.html
微信扫一扫
支付宝扫一扫