c++c++-coroutine

Can a C++ coroutine be wrapped in a normal function?


Is it legal and/or correct to wrap a coroutine with a normal function such that the normal function can be co_awaited?

Here's a minimal example of what I mean where a wrapper is just used to supply an input parameter to the actual coroutine function:

auto my_coroutine(int input) -> awaitable<int>
{
   // some normal coroutine activity... not important what it is
   auto result = co_await something();
   co_return result * input;
}

auto wrapper() -> awaitable<int>
{
   // Option A - wrapper is a normal function (allowed?)
   return my_coroutine(77);
   // Option B - wrapper is also a coroutine (unnecessary?)
   co_return co_await my_coroutine(77);
}

auto caller() -> awaitable<void>
{
   auto result = co_await wrapper();
   ...
}

Is option A above correct such that the co_await in caller is valid? The equivalent of this in my real code compiles and seems to work - just wanting to check I'm not missing something.

For context I'm using C++20's coroutines with Boost ASIO. I have a top level coroutine managing a client TCP connection which then needs to co_await on a separate coroutine that generates the response to each client request. The separate coroutine is a member function of an unrelated class and so I'm using a lambda as a wrapper to bind some arguments and call through to the correct object.


Solution

  • Yes: C++ coroutines have exactly the same call interface as any other function, as is necessary for separate translation of a coroutine’s source file. The only restriction is the usual copyability/movability of the return type (if you don’t just return a prvalue).