C++协程/Visual Studio:生成器如何调用代表它生成值的函数?

C++ coroutines / Visual Studio: How can a generator call a function that yields values on its behalf?

本文关键字:调用 函数 何调用 Visual 协程 Studio C++      更新时间:2023-10-16

在VS2015/Update 3中定义 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4628.pdf 的协程,生成器如何调用代表其发出值的函数?

澄清示例

我想编写如下代码...

static void yield_for_me()
{
co_yield 27; // does not compile 
//  co_yield relies on hidden definitions
}
std::experimental::generator<int> testf()
{
yield_for_me();
co_yield 28;
}

。希望它能有与以下代码完全相同的结果:

std::experimental::generator<int> testf()
{
co_yield 27;
co_yield 28;
}

在函数中使用co_yield/co_await/co_return会将其转换为协程,因此它需要有一个签名,允许编译器发现库类,向编译器解释该协程的含义。

Visual Studio 附带的生成器不支持将co_yield委派给另一个生成器。但要造出可以recursive_generator并不难。

下面是一个recursive_generator示例,它允许生成一个值或执行不同生成器的结果。

https://gist.github.com/GorNishanov/29e813139175b1c5299ad01021d2556d

recursive_generator的promise_type定义了两个yield_value函数:

yield_value(T const&); // This one yields individual values
yield_value(recursive_generator<T>&&); // delegates to another generator

使用上面的recursive_generator,只需将yield_from_me函数的返回类型从 void 更改为 recursive_generator即可。

recursive_generator<int> yield_for_me()
{
co_yield 27; 
}
recursive_generator<int> testf()
{
co_yield yield_for_me();
co_yield 28;
}

不能。这是 P0057 提出的协程模型的一个众所周知的限制。 尽管在本文中,它还描述了一个允许您执行以下操作的recursive_generator(未包含在 MSVC 中):

recursive_generator<int> yield_for_me()
{
co_yield 27;
}
recursive_generator<int> testf()
{
co_yield yield_for_me();
co_yield 28;
}

顺便说一句,这样的事情是在 CO2 中实现的,这是对所提出模型的模拟。