co_await
- C++ course
- Advanced
- Lesson 68/83
- 5 min
Learn await points with co_await.
What does co_await do?
co_await creates an await point inside a coroutine. The awaited object (awaitable) must be ready; until then the coroutine suspends, and when ready it continues.
An awaitable type must have three members: await_ready (is it ready?), await_suspend (how to suspend?) and await_resume (the value on resume). Example: int v = co_await Awaiter{};. Here Awaiter is an awaitable; the value returned by await_resume is assigned to v. This way asynchronous flow is written with synchronous-looking code.
Awaitable type
An awaitable is a type with await_ready, await_suspend and await_resume members. In its simplest form, a ready awaitable looks like this:
struct Awaiter { bool await_ready() { return true; } void await_suspend(std::coroutine_handle<>) { } int await_resume() { return 7; } };. Here await_ready returns true, so the coroutine is not suspended; await_resume returns 7. The expression co_await Awaiter{} yields the value 7. This structure represents the result of an asynchronous operation.
Practice Get a value with co_await
Write int v = co_await Awaiter{}; in the body of the run coroutine and print the value with std::cout << v;. In main call run();.
Starter code
#include <iostream>
#include <coroutine>
struct Awaiter {
bool await_ready() { return true; }
void await_suspend(std::coroutine_handle<>) { }
int await_resume() { return 7; }
};
struct Task {
struct promise_type {
Task 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_void() { }
void unhandled_exception() { }
};
std::coroutine_handle<promise_type> handle;
};
Task run() {
// Await the Awaiter with co_await and print the result
}
int main() {
// Call run
return 0;
}Sample solution
#include <iostream>
#include <coroutine>
struct Awaiter {
bool await_ready() { return true; }
void await_suspend(std::coroutine_handle<>) { }
int await_resume() { return 7; }
};
struct Task {
struct promise_type {
Task 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_void() { }
void unhandled_exception() { }
};
std::coroutine_handle<promise_type> handle;
};
Task run() {
int v = co_await Awaiter{};
std::cout << v;
}
int main() {
run();
return 0;
}Expected output
7
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 the co_await usage
int v = ____ Awaiter{};
int v = co_await Awaiter{};
Explanation: co_await awaits the Awaiter and assigns the result to v.
2 Match each member to its role
| Term | Meaning |
|---|---|
await_ready |
Is it ready? |
await_suspend |
How to suspend |
await_resume |
Resume value |
co_await |
Await expression |
3 What does co_await Awaiter{} return?
- The Awaiter struct itself
- A coroutine handle
- Nothing
- The value returned by await_resume Correct answer
Explanation: co_await yields the value returned by the awaitable's await_resume member.