Reputation: 163
With coroutines defined as of http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4628.pdf and implemented in VS2015/Update 3, how can a generator invoke a function that emits values on its behalf?
Clarifying example
I would like to write code as follows...
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;
}
...in hopes that it will have the exact same outcome as the following code:
std::experimental::generator<int> testf()
{
co_yield 27;
co_yield 28;
}
Upvotes: 1
Views: 2267
Reputation: 46
Using co_yield
/co_await
/co_return
in a function turns it into a coroutine, thus it needs to have a signature that allows compiler to discover library classes explaining to the compiler what that coroutine means.
The generator included with Visual Studio does not support delegating co_yield
to another generator. But is is not difficult to create a recursive_generator
that can.
Here is an example of a recursive_generator that allows to yield either a value or the result of execution of a different generator.
https://gist.github.com/GorNishanov/29e813139175b1c5299ad01021d2556d
The promise_type of the recursive_generator defines two yield_value
functions:
yield_value(T const&); // This one yields individual values
yield_value(recursive_generator<T>&&); // delegates to another generator
Using the recursive_generator above, just change the return type of yield_from_me function from void to recursive_generator and you are good to go.
recursive_generator<int> yield_for_me()
{
co_yield 27;
}
recursive_generator<int> testf()
{
co_yield yield_for_me();
co_yield 28;
}
Upvotes: 3
Reputation: 5309
It can't. It's a well-known limitation of the coroutine model proposed by P0057.
Although in the paper, it also describes a recursive_generator
(not included in MSVC) that allows you to do something like this:
recursive_generator<int> yield_for_me()
{
co_yield 27;
}
recursive_generator<int> testf()
{
co_yield yield_for_me();
co_yield 28;
}
BTW, such a thing is implemented in CO2, which is an emulation of the proposed model.
Upvotes: 3