CodeBlanks Logo Icon CodeBlanks

Summary - Coroutines

Combine co_await, co_yield and Task to write an async counter.

Summary - Coroutines

In this group you learned coroutine, co_await, co_return, co_yield and Task type.

A coroutine is a function that can be suspended and resumed. co_await creates an await point; co_return finishes by returning a value; co_yield produces a value and pauses. A Task type defines the coroutine behaviour through promise_type. Now you will write an async counter that combines these four: it will produce values with co_yield and run inside a generator frame.

Practice Write an async counter

Write co_yield 5; and co_yield 6; in the body of the counter coroutine. The resume and std::cout calls in main are ready; do not touch them.

Starter code

main.cpp
#include <iostream>
#include <coroutine>

struct Generator {
    struct promise_type {
        int value_;
        Generator get_return_object() { return {std::coroutine_handle<promise_type>::from_promise(*this)}; }
        std::suspend_always initial_suspend() { return {}; }
        std::suspend_always final_suspend() noexcept { return {}; }
        std::suspend_always yield_value(int v) { value_ = v; return {}; }
        void return_void() { }
        void unhandled_exception() { }
    };
    std::coroutine_handle<promise_type> handle;
};

Generator counter() {
    // Produce 5 and 6 with co_yield
}

int main() {
    auto g = counter();
    g.handle.resume();
    std::cout << g.handle.promise().value_;
    g.handle.resume();
    std::cout << g.handle.promise().value_;
    return 0;
}

Sample solution

main.cpp
#include <iostream>
#include <coroutine>

struct Generator {
    struct promise_type {
        int value_;
        Generator get_return_object() { return {std::coroutine_handle<promise_type>::from_promise(*this)}; }
        std::suspend_always initial_suspend() { return {}; }
        std::suspend_always final_suspend() noexcept { return {}; }
        std::suspend_always yield_value(int v) { value_ = v; return {}; }
        void return_void() { }
        void unhandled_exception() { }
    };
    std::coroutine_handle<promise_type> handle;
};

Generator counter() {
    co_yield 5;
    co_yield 6;
}

int main() {
    auto g = counter();
    g.handle.resume();
    std::cout << g.handle.promise().value_;
    g.handle.resume();
    std::cout << g.handle.promise().value_;
    return 0;
}

Expected output

56

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Match each idea to its description

Term Meaning
coroutine Suspendable function
co_await Await point
co_yield Produce a value
co_return Valued finish

2 Which keyword produces a value and pauses the coroutine?

  • co_await
  • co_return
  • return
  • co_yield Correct answer

Explanation: co_yield produces a value and suspends the coroutine.

3 the counter call

Question
auto g = ____();
Answer
auto g = counter();

Explanation: counter starts the generator coroutine.

All lessons in Advanced