An awaiter in C++ is an object that implements a specific interface required by theDocumentation Index
Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
Use this file to discover all available pages before exploring further.
co_await operator to control the suspension and resumption of a C++20 coroutine. It dictates whether a coroutine should suspend, executes logic immediately after the coroutine state is saved, and determines the evaluated result of the co_await expression upon resumption.
To qualify as an awaiter, a type must expose three specific methods: await_ready, await_suspend, and await_resume.
The Awaiter Interface Mechanics
When the compiler encounters aco_await expression, it interacts with the awaiter object through a strict sequence of operations.
1. await_ready()
This method acts as an optimization checkpoint. It returns a bool indicating whether the operation is already complete.
- If it returns
true, the coroutine does not suspend. The compiler skipsawait_suspendand immediately callsawait_resume. - If it returns
false, the coroutine prepares for suspension by saving its local state and instruction pointer to the heap-allocated coroutine frame.
2. await_suspend(std::coroutine_handle<>)
This method is invoked after the coroutine has been suspended and its state is safely stored. The compiler passes a std::coroutine_handle representing the currently suspended coroutine. This is the critical juncture where the awaiter can schedule the coroutine for future resumption.
The behavior of await_suspend is dictated by its return type:
void: Control is immediately returned to the caller or resumer of the current coroutine.bool: If it returnstrue, control returns to the caller/resumer. If it returnsfalse, the suspension is aborted, and the current coroutine is immediately resumed.std::coroutine_handle<P>: The compiler performs a symmetric transfer. It suspends the current coroutine and resumes the coroutine associated with the returned handle via a tail call (or by returning the handle to the underlying coroutine machinery). This avoids a nested function call, preventing stack overflow during chained coroutine executions.
3. await_resume()
This method is called when the coroutine is resumed (or immediately if await_ready returned true). The return type of await_resume becomes the return type of the entire co_await expression. If the method returns void, the co_await expression evaluates to void.
Awaitable vs. Awaiter Resolution
In C++ terminology, an Awaitable is any type that supports theco_await operator, while an Awaiter is the concrete object implementing the three methods above. The compiler resolves an Awaitable into an Awaiter through a sequential transformation pipeline:
- Promise Transformation: If the enclosing coroutine’s promise type defines
await_transform(expression), the compiler evaluatespromise.await_transform(expression). If not, the original expression is used. - Operator Overload: The compiler evaluates the result of step 1. If that result has an accessible
operator co_await()(either as a member function or a non-member function found via Argument-Dependent Lookup), the operator is invoked. If no such operator exists, the result of step 1 is used directly. - Direct Awaiter: The final result from step 2 is treated as the Awaiter and must implement the required
await_ready,await_suspend, andawait_resumemethods.
Conceptual Compiler Expansion
The following pseudo-code illustrates how the compiler expands aco_await expression. Explicit pseudo-code markers (bracketed in < >) are used to represent context-switching assembly and control flow interruptions that cannot be expressed in standard C++.
Trivial Standard Awaiters
The<coroutine> header provides two trivial awaiters that demonstrate the minimal implementation of the interface, primarily used by promise types to control initial and final suspension points:
Master C++ with Deep Grasping Methodology!Learn More





