What are coroutines?
- C++ course
- Advanced
- Lesson 67/83
- 5 min
Learn the C++20 coroutine concept.
What are coroutines?
A coroutine is a function that can be suspended and resumed. It entered the standard library with C++20. A normal function runs from start to end; a coroutine can pause at intermediate points and be resumed from outside.
Three keywords define a coroutine: co_await (await point), co_yield (produce a value) and co_return (finish). If a function uses any of these, it automatically becomes a coroutine. Coroutines let us write asynchronous operations, generators and state machines in a clean way.
Suspend and resume
A coroutine creates a coroutine frame when called. This frame stores local variables and state on the heap. When the function suspends, the frame stays; when resumed, it continues from the same state.
The return type of a coroutine must be a type that contains a promise_type. This type defines how the coroutine starts, finishes and returns a value. With std::coroutine_handle you manually resume or destroy the coroutine. This mechanism manages asynchronous flows in a type-safe way.
Practice Return a value with co_return
Write co_return 42; in the body of the make_value coroutine. In main get the value with promise().value_ from the result of make_value() and print it with std::cout.
Starter code
#include <iostream>
#include <coroutine>
struct Returner {
struct promise_type {
int value_;
Returner get_return_object() { return {std::coroutine_handle<promise_type>::from_promise(*this)}; }
std::suspend_never initial_suspend() { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void return_value(int v) { value_ = v; }
void unhandled_exception() { }
};
std::coroutine_handle<promise_type> handle;
};
Returner make_value() {
// Return 42 with co_return
}
int main() {
// Call make_value and print the value
return 0;
}Sample solution
#include <iostream>
#include <coroutine>
struct Returner {
struct promise_type {
int value_;
Returner get_return_object() { return {std::coroutine_handle<promise_type>::from_promise(*this)}; }
std::suspend_never initial_suspend() { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void return_value(int v) { value_ = v; }
void unhandled_exception() { }
};
std::coroutine_handle<promise_type> handle;
};
Returner make_value() {
co_return 42;
}
int main() {
auto r = make_value();
std::cout << r.handle.promise().value_;
return 0;
}Expected output
42
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 What is the difference between a coroutine and a normal function?
- A coroutine runs faster
- A coroutine can only be defined inside a class
- A coroutine can be suspended and resumed Correct answer
- A coroutine takes no parameters
Explanation: A coroutine is a function that can be suspended and resumed.
2 the coroutine keyword
Task run() { ____ 42; }
Task run() { co_return 42; }
Explanation: co_return finishes the coroutine and returns a value.
3 Match each piece to its role
| Term | Meaning |
|---|---|
co_await |
Await point |
co_yield |
Produce a value |
co_return |
Finish |
promise_type |
Behaviour contract |