A promise_type is the compiler-recognized part of a coroutine’s return type. It connects a returned Task to the coroutine frame and defines how results, exceptions, suspension, resumption, and completion are handled. The surrounding type may use any name, but its associated class must be called promise_type. section 8.3.1 section 8.3.3
A promise_type commonly supplies the following protocol:
- get_return_object creates the coroutine’s Task, typically passing the promise into a private constructor. section 8.3.4
- initial_suspend and final_suspend control whether execution pauses at the beginning and end; suspend_never gives a hot start, while suspend_always pauses. section 8.3.5
- unhandled_exception determines what happens when the coroutine body throws without handling the exception. section 8.3.5
- yield_value receives co_yield data, stores it for the Task, and usually returns suspend_always to give control back to the caller. section 8.3.5
- return_void handles co_return without a value; returning a value instead requires return_value. section 8.3.5
A coroutine game’s promise
A mind-reader coroutine yields a pair containing the player’s choice and the program’s prediction. Its promise stores that pair, suspends after each yield, starts immediately so input is ready, and suspends finally so the Task can detect completion. The Task owns the promise through a custom-deleter smart pointer that destroys the coroutine handle safely. section 8.3.5 section 8.3.4
Listing 8.17 Structure to wire up coroutine
#include <coroutine>
struct Task #1
{
struct promise_type #2
{
};
};
A minimal nested promise_type shows the required relationship between a coroutine return object and its promise before the operational functions are added. section 8.3.3
Listing 8.20 Complete promise type
struct promise_type
{
std::pair<int, int> choice_and_prediction; #1
Task get_return_object() #2
{
return Task(this);
}
std::suspend_never initial_suspend() noexcept #3
{
return {};
}
std::suspend_always final_suspend() noexcept #4
{
return {};
}
void unhandled_exception() {} #5
std::suspend_always yield_value(std::pair<int, int> got) #6
{
choice_and_prediction = got;
return {};
}
void return_void() { } #7
};
The completed promise type demonstrates result storage, Task creation, startup and completion suspension, exception handling, yielding, and co_return handling together. section 8.3.5
