c++如何利用协程实现一个生成器(Generator)_c++ co_yield的使用


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

c++如何利用协程实现一个生成器(generator)_c++ co_yield的使用

C++20 引入了协程(Coroutines)支持,使得我们可以用 co_yield 实现类似 Python 中的生成器(Generator)。通过协程,函数可以暂停执行并返回一个值,之后从中断处继续运行。这种机制非常适合实现惰性求值的序列,也就是“生成器”。

1. 生成器的基本结构

要实现一个生成器,我们需要定义一个返回类型,该类型满足协程的接口要求,通常包括 promise_typeget_return_objectinitial_suspendfinal_suspendunhandled_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;
};

2. 使用 co_yield 定义生成函数

有了上面的 Generator 类型后,就可以写一个使用 co_yield 的函数来生成一系列值。

Generator fibonacci() {
    int a = 0, b = 1;
    while (true) {
        co_yield a;
        int tmp = a + b;
        a = b;
        b = tmp;
    }
}

这个函数会无限生成斐波那契数列中的每一项。每次调用 co_yield 时,函数会保存状态并返回当前值,下次从下一条语句继续执行。

Krikey AI Krikey AI

Krikey AI 113 查看详情 Krikey AI

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_suspendsuspend_always 可以延迟执行,直到第一次 resume。
  • promise_type 是核心,它决定了协程的行为。
  • 协程句柄(coroutine_handle) 允许外部控制协程的生命周期和执行流程。

基本上就这些。C++ 的协程比 Python 更底层,需要手动管理一些细节,但灵活性更高。一旦封装好 Generator 类,使用起来就很接近传统意义上的生成器了。

以上就是c++++如何利用协程实现一个生成器(Generator)_c++ co_yield的使用的详细内容,更多请关注其它相关文章!


# ai  # 培训机构如何建设网站  # 阳春seo引流系统  # 福州网站建设产品介绍  # 苏州 关键词排名  # 威信网站推广怎么样啊  # 求值  # 句柄  # 几个  # 是一个  # 结束时  # 第三方  # 下次  # 遍历  # 挂起  # 自定义  # stream  # ios  # c++  # python  # 济南建设网站需求分析  # 广告优化师和seo排名  # 独立站seo自检手册  # 搜索穿越关键词排名优化  # 本地网站优化系统 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894


相关推荐: 《tt语音》超级玩家开通方法  AO3中文入口稳定分享_AO3官网HTTPS看文详解  Python中对象引用与链表属性赋值的机制解析  iPhone 14 Pro如何更改区域设置_iPhone 14 Pro地区语言修改教程  《七读免费小说》开通会员方法  在Peewee中处理PostgreSQL记录重复:一站式数据摄取教程  Golang如何使用crypto/md5生成哈希_Golang MD5哈希生成方法  yy漫画官方网站登录入口_yy漫画在线阅读页面地址  荣耀magicv5怎么上手测评  搜狗浏览器如何查找页面中的文字 搜狗浏览器Ctrl+F页面搜索功能  折叠屏手机充不进电是什么问题? 特殊结构带来的维修难点  OpenWeatherMap API:通过城市名称获取天气预报数据指南  c++20的指定初始化(Designated Initializers)怎么用_c++ C风格结构体初始化  PHP中获取HTTP响应状态消息:方法与限制  J*a里如何处理ArithmeticException并防止除零_算术异常防护策略解析  J*aScript对象中深度嵌套URL键的查找与更新策略  Flask 应用中图片动态更新与上传:实现客户端定时刷新与服务器端文件管理  手机远程连接电脑方法  CSS如何控制元素外边距_margin实现布局间隔  苹果手机聊天记录删除了如何恢复  Win10截图远程协助 Win10远程桌面截屏法【场景应用】  Teambition网盘如何共享文件  在XML中嵌入二进制数据(如图片)的最佳实践是什么? Base64编码与解析注意事项  C++ static关键字作用_C++静态成员变量与静态函数  MacBook Pro词典使用指南  韩剧圈正版官网入口_韩剧圈官方指定登录  iPhone 13 mini如何清理Safari缓存_iPhone 13 mini浏览器缓存清理方法  西瓜视频怎么查看访客记录_西瓜视频访客记录查看方法  2025考研成绩查询时间入口分享  如何查找哪个composer包引入了特定的依赖?  斯宾塞称XGP云游戏“蒸蒸日上”:正在构建一个游戏从未如此唾手可得的未来  百度小说看书时如何翻页_百度小说手动翻页与自动翻页设置  OPPO手机参数配置如何开启护眼模式_OPPO手机参数配置护眼模式开启指南  动漫之家观看全集库 动漫之家免费资源网地址  word邮件合并怎么插入个性化图片_Word邮件合并插入个性化图片方法  《雷电模拟器》自动点击设置方法  Flexbox布局:实现粘性导航与底部页脚的完美结合  招商淘客入门指南  B站怎么快速升级 B站用户等级提升攻略【详解】  126邮箱网页在线登录2025_126邮箱网页版入口官方地址  mysql如何配置从库只读_mysql从库只读设置方法  《知到》打卡课程方法  J*aScript装饰器_元编程实战  暴风影音官网正式版_暴风影音手机版官网下载安卓  吃完饭就犯困是什么原因 餐后嗜睡如何缓解  如何在CSS中使用伪类:valid实现表单验证提示_结合:valid改变边框颜色  解决异步Python机器人中同步操作的阻塞问题  PHP安全加载非公开目录图片与动态内容类型处理指南  智慧职教mooc平台登录网址 智慧职教mooc官网直达  解决CSS布局中意外顶部空白问题的教程 

 2025-12-04

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.