A coroutine is a function whose execution can be suspended and resumed while preserving its state. In C++, adding co_yield, co_await, or co_return makes a function a coroutine, provided it returns a suitable control object. section 8.3.1 section 8.4
co_yield returns a value and pauses execution; resuming continues from the next statement with the same local state. co_return completes the coroutine, while co_await supports asynchronous operations. section 8.3.1 section 8.3.2
A practical coroutine needs several cooperating pieces:
- Return a Task or another suitable object containing the boilerplate required to start, suspend, resume, and finish the coroutine. section 8.3.1 section 8.4
- Move the interaction boundary into the coroutine, yield a player choice and prediction, and let the caller display each result. section 8.3.2 section 8.3.7
- Use the returned object to test completion, read the yielded value, and resume execution with next(). section 8.3.7
A coroutine mind reader
The mind-reader game keeps its input, prediction state, and update logic inside coroutine_game. It uses co_return when input ends and co_yield { player_choice, mr.get_prediction() } on each turn. The caller obtains the pair, reports the outcome, and calls next() to resume the game. section 8.3.2 section 8.3.7
Listing 8.16 Our first coroutine
#include <coroutine>
struct Task; #1
Task coroutine_game() #2
{
std::mt19937 gen{ std::random_device{}() };
std::uniform_int_distribution dist{ 0, 1 };
MindReader mr(gen, dist);
while (true)
{
auto input = read_number(std::cin);
if (!input)
{
co_return; #3
}
int player_choice = input.value();
co_yield{ player_choice , mr.get_prediction() }; #4
mr.update(player_choice);
}
}
Inspect the compact coroutine function showing coroutine, co_return, and co_yield in a working game. section 8.3.2
Listing 8.22 A coroutine version of a mind reader
void coroutine_minder_reader()
{
int turns = 0;
int player_wins = 0;
std::cout << "Select 0 or 1 at random and press enter.\n";
std::cout << "If the computer predicts your guess it wins\n"
"and it can now read your mind.\n";
Task game = coroutine_game(); #1
while (!game.done()) #2
{
auto [player_choice, prediction] =
game.choice_and_prediction(); #3
++turns;
std::cout << "You pressed " << player_choice
<< ", I guessed " << prediction << '\n';
if (player_choice != prediction)
{
++player_wins;
}
game.next(); #4
}
std::cout << "you win " << player_wins << '\n'
<< "machine won " << (turns - player_wins) << '\n';
}
Inspect the calling loop that reads yielded values, checks completion, and resumes the coroutine. section 8.3.7







