通过c++20协程制作python生成器

如果你想这样做,你基本上有两个问题需要克服。

首先,C++是一种静态类型语言。这意味着在编译时需要知道所涉及的所有内容的类型。这就是为什么您的generator类型需要是模板,以便用户可以指定它从协程到调用者的引导类型。

因此,如果您想拥有这个双向接口,那么您的函数中的某些内容hello必须指定输出类型和输入类型。

最简单的方法是创建一个对象并将const对该对象的非引用传递给生成器。每次执行a时co_yield,调用者都可以修改引用的对象,然后请求新值。协程可以从引用中读取并查看给定的数据。

但是,如果您坚持使用协程的未来类型作为输出和输入,那么您需要解决第一个问题(通过使模板generator采用OutputType和InputType)以及第二个问题。

或者至少,它不能那么容易做到。

有两种方法可以根据不同的用例来实现此目的。第一个操纵协程机制,通过后门进入Promise。第二个操作的属性co_yield来执行基本相同的操作。

转换

协程的Promise对象通常是隐藏的并且无法从协程访问。它可以被Promise创建的future对象访问,并充当Promise数据的接口。但在机器的某些部分也可以访问它co_await。

具体来说,当您对协程中的任何表达式执行a时co_await,机器会查看您的Promise类型以查看它是否具有名为的函数await_transform。await_transform如果是这样,它将在您使用的每个表达式上调用该Promise对象co_await(至少在co_await您直接编写的表达式中,而不是隐式等待,例如由所创建的表达式co_yield)。

因此,我们需要做两件事:创建Promise类型的重载await_transform,并创建一个其唯一目的是允许我们调用该await_transform函数的类型。

所以看起来像这样:

structgenerator_input{};

...

//Withinthepromisetype:

autoawait_transform(generator_input);

快速说明一下。await_transform像这样使用的缺点是,通过为我们的Promise指定该函数的一个重载,我们会影响使用该类型的任何协程中的每个co_await重载。co_await对于生成器协程来说,这并不是很重要,因为除非您进行这样的黑客攻击,否则没有太多理由这样做。但是,如果您正在创建一个更通用的机制,可以在其生成过程中明确等待任意可等待项,那么您就会遇到问题。

OK,这样我们就有了这个await_transform功能;这个函数需要做什么?它需要返回一个可等待的对象,因为co_await它将等待它。但这个可等待对象的目的是传递对输入类型的引用。co_await幸运的是,用于将可等待转换为值的机制是由可等待的await_resume方法提供的。所以我们可以只返回一个InputType&:

//Withinthe`generator`:

structpassthru_value

{

InputType&ret_;

boolawait_ready(){returntrue;}

voidawait_suspend(coro_handle){}

InputType&await_resume(){returnret_;}

};

autoawait_transform(generator_input)

returnpassthru_value{input_value};//Where`input_value`isthe`InputType`objectstoredbythepromise.

}

这使协程可以通过调用来访问该值co_awaitgenerator_input{};。请注意,这将返回对该对象的引用。

该generator类型可以轻松修改,以允许修改InputType存储在Promise中的对象。只需添加一对send函数即可覆盖输入值:

voidsend(constInputType&input)

coro.promise().input_value=input;

voidsend(InputType&&input)

coro.promise().input_value=std::move(input);

总而言之,所需的代码并没有那么大。下面是经过这些修改的代码的可运行示例:

#include

#include

#include

#include

template

structgenerator{

structpromise_type;

usingcoro_handle=std::coroutine_handle;

structpromise_type{

OutputTypecurrent_value;

InputTypeinput_value;

autoget_return_object(){returngenerator{coro_handle::from_promise(*this)};}

autoinitial_suspend(){returnstd::suspend_always{};}

autofinal_suspend(){returnstd::suspend_always{};}

voidunhandled_exception(){std::terminate();}

autoyield_value(OutputTypevalue){

current_value=value;

returnstd::suspend_always{};

voidreturn_void(){}

returnpassthru_value{input_value};

boolnext(){returncoro(coro.resume(),!coro.done()):false;}

OutputTypevalue(){returncoro.promise().current_value;}

generator(generatorconst&rhs)=delete;

generator(generator&&rhs)

:coro(rhs.coro)

rhs.coro=nullptr;

~generator(){

if(coro)

coro.destroy();

private:

generator(coro_handleh):coro(h){}

coro_handlecoro;

generatorhello(){

autoword=co_awaitgenerator_input{};

for(auto&ch:word){

co_yieldch;

intmain(int,char**)

autotest=hello();

test.send("helloworld");

while(test.next())

变得更有收获

使用显式的替代方法co_await是利用的属性co_yield。即,co_yield是一个表达式,因此它有一个值。具体来说,它(大部分)相当于co_awaitp.yield_value(e)Promisep对象(哦!),并且e是我们要产生的对象。

幸运的是,我们已经有了一个yield_value函数;它返回std::suspend_always。但它也可以返回一个始终挂起的对象,但也可以将其co_await解包为InputType&:

structyield_thru

boolawait_ready(){returnfalse;}

//inthepromise

returnyield_thru{input_value};

这是一种对称传输机制;对于您产生的每一个值,您都会收到一个值(可能与以前的值相同)。与显式方法不同,在开始生成它们之前co_await您无法接收值。这对于某些接口可能很有用。

THE END
1.C++编译器下载C++编译器手机版2024官方下载想要查找手机版C++编译器下载安装?PP提供C++编译器2024版官方下载。C++编译器是一款的APP,主要为C++语言初学者提供核心的功能,验证一些小程序。该软件支持直接从文件管理器代码文件,方便用户查看。 C++编译器更新说明: 使用全新的编译模块 C++编译器10.4.1下载安装说明: 下载C++编译器到手机上面方法有很多。卓系统的手https://wap.pp.cn/app_BywhcxYDgzu/
2.C#编程工具MicrosoftLearnRoland Weigelt 的 GhostDoc 数据库 ADO.NET Express .NET 的数据访问应用程序块 DeKlarit OlyMars 正则表达式 GotDotNet 用户示例:Regular Expression Workbench (V2.00) 正则表达式设计器 Expresso—正则表达式生成和测试工具 图形、游戏和绘图 CadLib Sharp3D.Math 库 动态矢量图https://msdn.microsoft.com/zh-cn/vcsharp/aa336818.aspx
3.码上去学海南公司:打造属于你的C++工具库,从零开始封装通用工具函数今天码上去学海南公司就来聊聊,如何从零开始打造一套属于自己的 C++ 工具库,轻松提高开发效率。别担心,这事儿没那么复杂,写工具库就像收拾房间,收拾得当,日后用起来省事儿! 1、工具库的基本架构 要写工具库,先整点架子出来。一个好的工具库架构,应该清晰明了,方便扩展。通常,我们会把工具函数分成多个模块,比如https://zhuanlan.zhihu.com/p/12437258596
4.C++随机点名生成器实例代码(老师们的福音!)C语言rand()函数不接受参数,默认以1为种子(即起始值)。 随机数生成器总是以相同的种子开始,所以形成的伪随机数列也相同,失去了随机意义。若要不同,此时需要使用函数srand()进行初始化。 完整示例代码: #include <bits/stdc++.h> #include <conio.h> #include <windows.h>https://m.jb51.net/article/152475.htm
5.C++程序文档生成器介绍(doxygen)C++ 程序文档生成器介绍(doxygen) 程序文档,曾经是程序员的一个头痛问题。写一个程序文档,比较花时间,但不是很难;麻烦的是当程序修改后,程序文档也要跟着同步更新,否则文档和程序就要脱节,文档也就变成没用的东西了。 好在有许多好用的文档生成器来解决这个问题。目前比较流行的C++文档生成器是doxygen。 本文就https://www.pianshen.com/article/7020452189/
6.BMP(Bitmap)生成器,纯C++实现由数组生成位图本篇文章将详细讲解如何使用C++编程语言,特别是Microsoft VisualC++(VC)环境,来实现JPEG图像到BMP图像的转换。 首先,我们需要了解JPEG(Joint Photographic Experts Group)和BMP(Bitmap)这两种图像格式的 ico图标生成器源码 浏览:71 4星 · 用户满意度95% https://download.csdn.net/download/ruby97/4245674
7.卡诺图生成器.rar卡诺图生成,卡诺图生成器本人某大学本科生,今年大二。最近学习数电的过程中了解了逻辑函数以及用卡诺图对其进行化简,于是便萌生了编写一个程序绘制卡诺图并化简逻辑函数的想法。经过两天的努力,已经基本可以实现功能(包括卡诺图的生成、最简表达式的写出等),希望可以帮助到有需要的同学。https://www.coder100.com/index/index/content/id/1007551
8.al图片生成器al生成器支持多种语言:al生成器支持多种编程语言,包括Java、Python、C++等。无论开发人员使用哪种语言,都可以使用al生成器来生成符合规范的代码。 如何使用al生成器 使用al生成器非常简单。首先,开发人员需要安装al生成器的软件包。然后,在命令行中输入相应的命令,即可开始使用al生成器。 https://tool.a5.cn/article/show/82255.html
9.强密码生成器(C++)强密码生成器(C++) 这几天闲着没事又想着用C++做一个密码生成器,方便我以后生成不容易破解密码,并且我还出了几种模式,感兴趣的可以下载下来看看。 ==上代码== (备注:https://www.jianshu.com/p/976397fb8290
10.C++随机数生成器深入解析C++随机数生成器mersenne在探索 C++ 的随机数生成之前,我们首先需要了解其背后的历史和动机。为什么我们需要随机数?为什么 C++ 为我们提供了这么多的随机数生成器?这些问题的答案不仅仅涉及技术,还涉及人性。 1.1 C++ 的随机数生成简史 在早期的 C 和 C++ 版本中,随机数生成主要依赖于rand()函数和srand()函数来设置种子。这些函数简单且https://developer.aliyun.com/article/1467691
11.恶搞新闻联播图片生成器露水晨曦由于我今天无聊看新闻联播,突发奇想,人们都用PS来制作那种新闻联播恶搞的图片,我想,能不能直接利用软件来恶搞出这类图片呢?结果,一个软件便诞生了,那就是今天的主题 “恶搞新闻联播图片生成器” 顾名思义,这个软件就是用来恶搞新闻联播上的图片的,先给大家看一个图片。 https://www.lscx.org/?p=1217
12.C++代码生成器三层模式标准版,版演示源码,代码生成,非托管代码,基于对话框程序,分类,猛犸代码生成器,人阅读评论,收藏举报本演示项目由猛犸代码生成器自动生成,环境,非托管代码,基于对话框程序,代码生成器,三层架构发布新的,代码生成模板,三层标准版,生成的https://www.jinchutou.com/shtml/view-472177562.html
13.Visustin—流程图生成器Visustin是专为软件开发人员设计的一款流程图生成器。自动将源代码转换为流程图和流程图和UML活动图。只需鼠标即可绘制流程图。参看并打印图表或导出至Visio。自动将源代码转换为流程图! 理解并完善您的算法。 下载演示版 现在就订购吧!Visustin支持49种编程语言 ABAP ActionScript Ada Assembler: –IAR/MSP430 https://www.aivosto.com/visustin-zh-hans.html
14.c++随机数生成器的实现[副本]你可以得到随机数生成器,比如在Linux下阅读/dev/random,但是C库附带的普通随机数生成器通常没有。最https://www.saoniuhuo.com/question/detail-2286301.html
15.C++中的种子随机数生成器前一种方法的问题是用户可以多次输入相同的数字。如果你需要确保每次执行算法时都提供不同的种子,请使用time()函数为伪随机数生成器提供种子。 C++ 中的time()函数返回当前 UNIX 时间戳,即自 UTC 时间 1970 年 1 月 1 日 00:00 小时以来经过的秒数。 https://www.jiyik.com/tm/xwzj/prolan_5622.html
16.C++随机点名生成器实例代码(老师们的福音!)rand()函数不接受参数,默认以1为种子(即起始值)。 随机数生成器总是以相同的种子开始,所以形成的伪随机数列也相同,失去了随机意义。若要不同,此时需要使用函数srand()进行初始化。 完整示例代码: #include <bits/stdc++.h> #include <conio.h> #include <windows.h>https://www.xiuzhanwang.com/a1/Cyuyan/638.html
17.C++代码生成器:xsd2ccxsd2cc开发语言与工具Xsd2cc是一个霸气的C++代码生成器,直接从指定的XML数据格式定义文件(.xsd)生成对应的C++类代码,然后将这些代码和xsd2cc库结合(自带的),就可以非常方便的写XML数据解析了(未来准备自动生成)。Xsd2cc是基于C++的对象模型构建的,仅仅依赖libxml库,支持快速、高效的XML文档解析。Xsd2cc是由STL实现,无异常,无需手工https://www.open-open.com/lib/view/open1414977826184.html
18.设计模式——建造者模式/生成器模式(C++实现)码农的逼格设计模式——建造者模式/生成器模式(C++实现) 1#include <iostream>2#include <string>34usingnamespacestd;56classSTProduct7{8public:9voidsetA(stringstr)10{11m_a =str;12}1314voidsetB(stringstr)15{16m_b =str;17}1819voidsetC(stringstr)20{21m_c =str;22}2324voidShow()25{26cout<<"Product:"<https://www.cnblogs.com/070412-zwc/p/6834417.html
19.身份证照片生成器生成器华为云帮助中心为你分享云计算行业信息,包含产品介绍、用户指南、开发指南、最佳实践和常见问题等文档,方便快速查找定位问题与能力成长,并提供相关资料和解决方案。本页面关键词:身份证照片生成器。https://support.huaweicloud.com/topic/343468-1-S
20.「定义阵营图」(「逐渐离谱」九宫格)生成器这种九宫格图的正式名称应该为 「定义阵营图」。 叫这个名字是因为不知道怎么形容最近流行的这种九宫格所以就干脆起名叫「逐渐离谱九宫格」了。 总而言之,就是个生成器。「阵营九宫格生成器」的精神续作。事实上只是稍微改了下代码。 前端技术有限,使用的都是上古时代的技术。大概会翻新?不知道呢 网址在http://bgm.tv/group/topic/357445
21.RapidJSON:首页进阶 prettyauto: pretty 的修改版本,可自动处理任何 UTF 编码的 JSON。 parsebyparts: 这例子中的 AsyncDocumentParser 类使用 C++ 线程来逐段解析 JSON。 filterkey: 移取使用者指定的键值的命令行工具。 filterkeydom: 如上的工具,但展示如何使用生成器(generator)去填充一个 Document。 https://rapidjson.org/zh-cn/
22.matlab图形axesmatlab中awgnmob64ca13f63f2c的技术博客`seed` - 随机数生成器种子 `powertype` - 信号功率单元 输出参数 `out` - 输出信号 提示 扩展功能 C/C++ 代码生成 另请参阅 函数 对象 话题 awgn:在信号中添加高斯白斯噪声 语法 out = awgn(in,snr)out = awgn(in,snr,signalpower) out = awgn(in,snr,signalpower,randobject)out = awgn(in,snr,https://blog.51cto.com/u_16213575/10664896
23.GitHubgeosson/awesomecppRapidJSON:用于C++的快速JSON 解析生成器,包含SAX和DOM两种风格的API。官网 YAJL:C语言中快速流JSON解析库。官网 日志 Boost.Log:设计非常模块化,并且具有扩展性。官网 easyloggingpp:C++日志库,只包含单一的头文件。官网 Log4cpp:一系列C++类库,灵活添加日志到文件,系统日志,IDSA和其他地方。官网 https://github.com/geosson/awesome-cpp-cn