【问题标题】:C++ coroutines / Visual Studio: How can a generator call a function that yields values on its behalf?C++ 协程/Visual Studio:生成器如何调用代表它产生值的函数?
【发布时间】:2017-08-05 16:59:24
【问题描述】:

使用从 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;
}

【问题讨论】:

  • 对此的自然跟进是“co_yield 关键字在后台生成的等效 c++ 代码是什么”? - 了解底层的脚手架会很有帮助。
  • 并不是说它有帮助:鉴于链接的规范,我似乎没有看到一种方法——python中的等价物是yield from——希望它们在c++中实现类似的东西:)

标签: c++ generator coroutine


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    不能。这是 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 中实现的,这是对提议模型的模拟。

    【讨论】:

      猜你喜欢
      • 2020-10-29
      • 1970-01-01
      • 2012-07-29
      • 2019-10-03
      • 2016-05-20
      • 2023-03-05
      • 1970-01-01
      • 1970-01-01
      • 2010-09-06
      相关资源
      最近更新 更多