我进入协同例程迟到了;但是现在C ++ 20已经有了它们,可以这么说。具体来说,我在Timur Doumler的this CppCon20 talk中观看了有关协程的片段。
Timur首先说明如何使用带有函数和协程(或协程和相关的生成器)的协程:
my_generator<int> f() {
int i = 0;
while (true)
co_yield i++;
}
void foo() {
auto g = f();
std::cout << g() << '\n';
std::cout << g() << '\n';
std::cout << g() << '\n';
}
稍后,他在该细分受众群中介绍co_await
,例如:
async_generator<T> f1() {
// code
auto u = co_await f2();
// more code
co_return u;
}
async_generator<U> f2() {
// code
co_yield u;
}
现在,我不明白的是,第二个示例与仅调用第一个示例中的协程不同,例如:
async_generator<T> f1() {
auto g2 = f2();
// code
auto u = g2();
// more code
co_return u;
}
async_generator<U> f2() {
// code
co_yield u;
}
我尝试寻找co_await
on cppreference,并且确实存在,但是-它链接到一般的coroutines page-老实说,我从树上看不见森林。我宁愿不知道所有细节-现在。我只想了解高层的概念差异。
答案 0 :(得分:1)
co_yield
语句仅在存在暂停上下文时才有意义。生成器的悬浮上下文的一个示例是在循环内使用co_yield(为某些条件提供值)。
在此示例中:
async_generator<T> f1() {
// code
auto u = co_await f2();
// more code
co_return u;
}
async_generator<U> f2() {
// code
co_yield u;
}
co_yeild不与任何暂停上下文相关联,因此它将作为典型函数起作用(即co_yield被解释为正常的return语句)。 auto u
将等到f2
到达函数末尾,从而使执行工作成为典型的函数调用语义。
在此示例中:
async_generator<T> f1() {
auto g2 = f2();
// code
auto u = g2();
// more code
co_return u;
}
async_generator<U> f2() {
// code
co_yield u;
}
同样,由于缺少 promise对象的创建和操作,因此缺少了悬浮上下文。因此,该代码将与前面的示例完全相同。
但是,如果示例在暂停上下文方面有所不同,则co_yield的工作方式可能有所不同。
here找到了关于协程与诺言对象之间相互作用的权威解释(使用co_await和co_yield)。