liveBook · Manning

Coroutine task

As explained in Learn C++ by Example

A coroutine task is a user-defined return type that packages the state and operations needed to manage a coroutine's suspension, resumption, yields, and completion.

A coroutine task is a user-defined return type that packages the state and operations needed to suspend, resume, yield values, and detect completion. The coroutine returns a Task, while its nested promise_type supplies the compiler-required machinery. section 8.3.1 section 8.3.3

Build a practical Task by adding these responsibilities:

  • Define a coroutine function containing co_yield and co_return, returning Task. section 8.3.2
  • Add a nested promise_type with get_return_object, initial_suspend, final_suspend, yield_value, return_void, and unhandled_exception. section 8.3.5
  • Store yielded data in the promise so Task can expose it to calling code. section 8.3.5
  • Use a coroutine handle to implement done and next, letting callers inspect completion and resume execution. section 8.3.6
  • Manage the coroutine frame with RAII, a custom unique_ptr deleter, and move-only ownership. section 8.3.4

Mind-reader game

coroutine_game reads a player choice, yields the choice and the mind reader’s prediction, then pauses. Calling code displays the pair and calls game.next() to continue. When input ends, co_return completes the Task. section 8.3.2 section 8.3.7

Listing 8.21 The coroutine's Task and promise_type
struct Task                                         #1
{
    struct promise_type                             #2
    {
    // ...
    };
 
    std::pair<int, int> choice_and_prediction()     #3
    {
        return promise->choice_and_prediction;
    }
    bool done() const                               #4
    {
        auto handle =
            std::coroutine_handle<promise_type>::from_promise(*promise);
        return handle.done();
    }
    void next()                                     #5
    {
        auto handle =
            std::coroutine_handle<promise_type>::from_promise(*promise);
        return handle ();
    }
private:
    promise_ptr<promise_type> promise;              #6
    Task(promise_type* p) : promise(p) {}           #7
}; 

Inspect the complete Task and promise_type structure, including yielded-value access, completion checking, resumption, and private ownership. section 8.3.6

How Learn C++ by Example covers it

How deep it goes
Descends from coroutine syntax through promise methods, handles, frame lifetime, and RAII, while leaving generalized designs to later use.
Examples
Demonstrates a mind-reader game that yields player choices and predictions through a manually controlled Task.
What it assumes
Assumes basic C++ classes, smart pointers, RAII, and function use while teaching coroutine return objects and promise machinery incrementally.
What you can do after
Build and operate a C++20 Task using promise_type, coroutine handles, co_yield, co_return, done, and next.
How it connects
Connects coroutines with promise_type, coroutine handles, RAII, unique_ptr, suspension, and constrained concurrency.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn C++ by Example. The section links point to the parts of the book it draws on.