Date: Thu, 11 Sep 2025 14:21:34 +0300
The Standard says
> If searches for the names return_void and return_value in the scope
of the promise type each find any declarations, the program is ill-
formed.
However, there are cases where one wants both "co_return;" and
co_return something;" statements in the same coroutine.
The cases are when the coroutine returns a sum type such as std::future
or std::expected, and one of the options is void (e.g.
std::future<void> or std::expected<void, something>. In these cases,
one would want
co_return;
to select the void branch of the sum type
and
co_return std::make_exception_ptr(...) // for std::future<void>
or
co_return something(...) // for std::expected<void, something>.
to select the non-void branch.
Early versions of gcc did not error when both return_value() and
return_void() were defined; no problems were observed.
Proposal:
- remove this requirement from the Standard.
Alternatives:
1. Co-opt co_await to return (suggested by this list some time ago);
this is what I use now in Seastar. It's unsatisfying to use co_await
when you mean to return.
2. Use co_return some_dummy_type() to force both branches to use
return_value(). Again unsatisfying to force users to type out a dummy
type when they want a non-erroneous return; also forces co_return when
falling off the end.
> If searches for the names return_void and return_value in the scope
of the promise type each find any declarations, the program is ill-
formed.
However, there are cases where one wants both "co_return;" and
co_return something;" statements in the same coroutine.
The cases are when the coroutine returns a sum type such as std::future
or std::expected, and one of the options is void (e.g.
std::future<void> or std::expected<void, something>. In these cases,
one would want
co_return;
to select the void branch of the sum type
and
co_return std::make_exception_ptr(...) // for std::future<void>
or
co_return something(...) // for std::expected<void, something>.
to select the non-void branch.
Early versions of gcc did not error when both return_value() and
return_void() were defined; no problems were observed.
Proposal:
- remove this requirement from the Standard.
Alternatives:
1. Co-opt co_await to return (suggested by this list some time ago);
this is what I use now in Seastar. It's unsatisfying to use co_await
when you mean to return.
2. Use co_return some_dummy_type() to force both branches to use
return_value(). Again unsatisfying to force users to type out a dummy
type when they want a non-erroneous return; also forces co_return when
falling off the end.
Received on 2025-09-11 11:21:40