tts*_*ras 30 c++ yield c++11 c++17
我在许多Python程序中都使用了yield,在很多情况下它确实清除了代码.我在博客上写了这篇文章,这是我网站的热门网页之一.
C#还提供了收益 - 它通过调用者端的状态保持来实现,通过自动生成的类来完成,该类保持状态,函数的局部变量等.
我目前正在阅读有关C++ 0x及其添加的内容; 在阅读有关C++ 0x中lambda的实现时,我发现它也是通过自动生成的类完成的,配备了存储lambda代码的operator().我心中形成了一个自然的问题:他们是为lambdas做过的,他们为什么不考虑支持"收益"呢?
当然,他们可以看到合作例程的价值......所以我只能猜测他们认为基于宏的实现(例如Simon Tatham的)是一个充分的替代品.然而,它们不是出于多种原因:被调用者保持状态,非重入状态,基于宏观(仅此一点是足够的理由)等.
编辑: yield不依赖于垃圾收集,线程或光纤.您可以阅读Simon的文章,看看我在谈论编译器进行简单的转换,例如:
int fibonacci() {
int a = 0, b = 1;
while (true) {
yield a;
int c = a + b;
a = b;
b = c;
}
}
Run Code Online (Sandbox Code Playgroud)
成:
struct GeneratedFibonacci {
int state;
int a, b;
GeneratedFibonacci() : state (0), a (0), b (1) {}
int operator()() {
switch (state) {
case 0:
state = 1;
while (true) {
return a;
case 1:
int c = a + b;
a = b;
b = c;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
垃圾收集?号码线程?不是纤维?不.简单转型?可以说是的.
jal*_*alf 22
我不能说为什么他们不添加这样的东西,但在lambdas的情况下,他们不仅仅是添加到语言中.
他们在Boost中开始了作为库实现的生活,证明了这一点
基于此,委员会决定在C++ 0x中采用某种 lambdas,我相信他们最初尝试添加更多通用语言功能,以允许比Boost 更好的库实现.
最终,他们将其作为核心语言功能,因为他们没有别的选择:因为不可能做出足够好的库实现.
新的核心语言功能并不是简单地添加到语言中,因为它们似乎是个好主意.委员会非常不愿意添加它们,所讨论的功能确实需要证明自己.必须证明该功能是:
在yield关键字的情况下,我们知道第一点可以解决.如您所示,这是一个相当简单的转换,可以通过机械方式完成.
第二点很棘手.有多少需要呢?存在的库实现有多广泛使用?有多少人要求这样做,或者为此提交了提案?
最后一点似乎也过去了.至少在C++ 03中,正如你所指出的那样,库实现会遇到一些缺陷,这可能证明核心语言的实现是合理的.可以在C++ 0x中实现更好的库实现吗?
所以我怀疑主要问题确实是缺乏兴趣.C++已经是一种庞大的语言,除非添加的功能非常值得,否则没有人希望它变得更大.我怀疑这只是不够用.
添加关键字总是很棘手,因为它会使先前有效的代码无效.您试图在具有与C++一样大的代码库的语言中避免这种情况.
C++的发展是一个公共过程.如果您认为yield应该在那里,请向C++标准委员会提出适当的请求.
您将直接从做出决定的人那里得到答案.
小智 7
他们为lambdas做了这个,他们为什么不考虑支持产量呢?
检查文件.有人提出过吗?
......我只能猜测他们认为基于宏的实现是一个充分的替代品.
不必要.我确信他们知道存在这样的宏观解决方案,但是替换它们并不足以让新功能通过.
尽管围绕新关键字存在各种问题,但可以使用新语法克服这些问题,例如对lambdas执行并使用auto作为函数返回类型.
从根本上来说,新功能需要强大的驱动力(即人员)来通过委员会来全面分析和推动功能,因为他们总是会有很多人对激进的变革持怀疑态度.因此,即使没有你认为对抗收益率构造的强大技术理由,也可能仍然没有得到足够的支持.
但从根本上说,C++标准库已经采用了与使用yield看到的不同的迭代器概念.与Python的迭代器相比,它只需要两个操作:
C++的迭代器成对使用(必须是相同的类型),分为类别,它将是一种语义转换,可以转换为更适合于yield构造的东西,并且这种转换不适合概念(具有自从被淘汰以来,但来得相对较晚).例如,见理的(理直气壮,如果令人失望)拒绝我的评论改变基于范围for循环的形式,将使写这不同形式的迭代器容易得多.
具体说明我对不同迭代器形式的含义:生成的代码示例需要另一种类型作为迭代器类型以及用于获取和维护这些迭代器的相关机制.并不是说它无法处理,但它并不像你最初想象的那么简单.真正的复杂性是关于"局部"变量(包括构造期间)的异常的"简单转换",控制生成器内局部范围内的"本地"变量的生命周期(大多数需要跨调用保存),等等.
所以看起来它没有进入C++ 11或C++ 14,但可能正在进入C++ 17.看一下C++ Coroutines的演讲,CppCon2015的负面开销抽象和这里的论文.
总而言之,他们正在努力扩展c ++函数以获得收益并等待函数的功能.看起来他们在Visual Studio 2015中有一个初始实现,不确定clang是否还有一个实现.它似乎也可能是使用yield并等待作为关键字的一些问题.
演示文稿很有意思,因为他谈到了简化网络代码的程度,等待数据进入以继续处理的顺序.令人惊讶的是,看起来使用这些新的协同程序会产生比现在更快/更少的代码.这是一个很棒的演讲.
可在此处找到C++的可恢复功能提议.