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

C++20 引入了协程(Coroutines)支持,使得我们可以用 co_yield 实现类似 Python 中的生成器(Generator)。通过协程,函数可以暂停执行并返回一个值,之后从中断处继续运行。这种机制非常适合实现惰性求值的序列,也就是“生成器”。
要实现一个生成器,我们需要定义一个返回类型,该类型满足协程的接口要求,通常包括 promise_type、get_return_object、initial_suspend、final_suspend 和 unhandled_exception 等组件。
下面是一个简单的整数生成器示例:
#include <coroutine>
#include <iostream>
struct Generator {
struct promise_type {
int current_value;
// 返回生成器对象
Generator get_return_object() {
return Generator{std::coroutine_handle<promise_type>::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<promise_type>;
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;
};有了上面的 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 时,函数会保存状态并返回当前值,下次从下一条语句继续执行。
使用前面定义的 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
initial_suspend 用 suspend_always 可以延迟执行,直到第一次 resume。基本上就这些。C++ 的协程比 Python 更底层,需要手动管理一些细节,但灵活性更高。一旦封装好 Generator 类,使用起来就很接近传统意义上的生成器了。
以上就是c++++如何利用协程实现一个生成器(Generator)_c++ co_yield的使用的详细内容,更多请关注php中文网其它相关文章!
c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号