Ожидание в сопрограмме в C++
Выражение co_await работает с
объектом, у которого есть await_ready,
await_suspend и await_resume.
Если await_ready возвращает
false, управление уходит в
await_suspend, а после resume
вызывается await_resume. Запишем
крошечный awaitable и сопрограмму, которая
завершается полученным числом:
#include <coroutine>
#include <iostream>
struct tiny_awaitable {
bool await_ready() const noexcept { return false; }
void await_suspend(std::coroutine_handle<> handle) const {
std::cout << "pause\n";
(void)handle;
}
int await_resume() const noexcept { return 1; }
};
struct wait_job {
struct promise_type {
int result = 0;
wait_job get_return_object() {
return wait_job{
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 value) { result = value; }
void unhandled_exception() { std::terminate(); }
};
std::coroutine_handle<promise_type> h;
explicit wait_job(std::coroutine_handle<promise_type> handle)
: h(handle) {}
~wait_job() {
if (h) {
h.destroy();
}
}
wait_job(const wait_job&) = delete;
wait_job& operator=(const wait_job&) = delete;
};
static wait_job probe() {
int value = co_await tiny_awaitable{};
co_return value;
}
int main() {
wait_job job = probe();
while (!job.h.done()) {
job.h.resume();
}
std::cout << job.h.promise().result << "\n";
return 0;
}
Цикл крутит resume, пока сопрограмма
не дойдет до конечной приостановки, и только
после этого читает сохраненный результат.
Создайте awaitable, у которого
await_resume возвращает 4.
Передайте это значение в co_return
и выведите поле result.
В await_suspend выведите слово
"wait" и верните управление без
аргумента. Доведите сопрограмму до конца
через resume в main.