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

时间:2017-03-15 05:12:26

标签: c++ generator coroutine

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

澄清示例

我想编写如下代码......

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;
}

2 个答案:

答案 0 :(得分:3)

它不能。它是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;
}

BTW,这样的事情是在CO2中实现的,这是对所提议模型的仿真。

答案 1 :(得分:2)

在函数中使用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;
}