Task type
- C++ course
- Advanced
- Lesson 71/83
- 5 min
Learn Task and promise types.
Task and promise type
A Task type is the return type of a coroutine and it contains a promise_type inside. The promise_type defines how the coroutine starts, finishes and returns a value.
A promise_type must have these members: get_return_object (produces the Task object), initial_suspend (suspend at start), final_suspend (suspend at finish), return_void or return_value (finish) and unhandled_exception (error). These members form the skeleton of the coroutine. If any is missing, you get a compile error.
Suspend members
initial_suspend and final_suspend decide what happens at the start and end of the coroutine. If they return std::suspend_never the coroutine runs immediately; if they return std::suspend_always it suspends.
A Task commonly uses suspend_never for initial_suspend (start immediately) and suspend_always for final_suspend (keep the frame). This way the coroutine starts, produces a value, and when it finishes the frame stays; it can be read from outside. They are also marked noexcept because final_suspend must not throw.
Practice Complete the Task promise_type
Add std::suspend_never initial_suspend() { return {}; } and std::suspend_never final_suspend() noexcept { return {}; } members into the promise_type. The code in main is ready; do not touch it.
Starter code
#include <iostream>
#include <coroutine>
struct Task {
struct promise_type {
Task get_return_object() { return {std::coroutine_handle<promise_type>::from_promise(*this)}; }
// Add initial_suspend and final_suspend
void return_void() { }
void unhandled_exception() { }
};
std::coroutine_handle<promise_type> handle;
};
Task run() {
co_return;
}
int main() {
run();
std::cout << "Task test passed";
return 0;
}Sample solution
#include <iostream>
#include <coroutine>
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_never final_suspend() noexcept { return {}; }
void return_void() { }
void unhandled_exception() { }
};
std::coroutine_handle<promise_type> handle;
};
Task run() {
co_return;
}
int main() {
run();
std::cout << "Task test passed";
return 0;
}Expected output
Task test passed
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 the promise_type member
struct promise_type { Task ____() { return {}; } };
struct promise_type { Task get_return_object() { return {}; } };
Explanation: get_return_object produces the Task object from the promise.
2 What does promise_type do?
- It speeds up the coroutine
- It deletes the coroutine
- It defines the start, finish and return behaviour of the coroutine Correct answer
- It counts the coroutine parameters
Explanation: promise_type defines the behaviour contract of the coroutine.
3 Match each member to its role
| Term | Meaning |
|---|---|
get_return_object |
Produces the Task object |
initial_suspend |
Start suspend |
final_suspend |
Finish suspend |
unhandled_exception |
Error handling |