Ключевое слово co_await
Ключевое слово co_await применяется внутри корутин
для приостановки их выполнения до тех пор, пока не завершится
некоторая асинхронная операция. Операндом выступает объект,
поддерживающий протокол awaitable - например, задача, таймер
или другая корутина. Пока ожидание активно, управление
возвращается вызывающей стороне, а после готовности результата
корутина возобновляется, и co_await возвращает
полученное значение. Использовать co_await можно
только внутри функции, объявленной как корутина (то есть
содержащей co_await, co_yield или
co_return).
Синтаксис
auto res = co_await expression;
Пример
Рассмотрим простейшую корутину, которая приостанавливается
на заранее подготовленном awaitable-объекте и возвращает
число 42:
#include <iostream>
#include <coroutine>
using namespace std;
struct Task
{
struct promise_type
{
Task get_return_object()
{
return {};
}
suspend_never initial_suspend()
{
return {};
}
suspend_never final_suspend() noexcept
{
return {};
}
void return_void()
{
}
void unhandled_exception()
{
}
};
};
struct Awaitable
{
bool await_ready()
{
return false;
}
void await_suspend(coroutine_handle<>)
{
}
int await_resume()
{
return 42;
}
};
Task coro()
{
int res = co_await Awaitable{};
cout << res << endl;
}
int main()
{
coro();
return 0;
}
Результат выполнения кода:
42
Пример
Теперь используем co_await для ожидания
готовности другой корутины и выведем строку
"abcde" после её завершения:
#include <iostream>
#include <coroutine>
using namespace std;
struct Task
{
struct promise_type
{
Task get_return_object()
{
return {};
}
suspend_never initial_suspend()
{
return {};
}
suspend_never final_suspend() noexcept
{
return {};
}
void return_void()
{
}
void unhandled_exception()
{
}
};
};
struct StringAwaitable
{
bool await_ready()
{
return false;
}
void await_suspend(coroutine_handle<>)
{
}
const char* await_resume()
{
return "abcde";
}
};
Task inner()
{
cout << "inner done" << endl;
co_return;
}
Task outer()
{
co_await inner();
const char* res = co_await StringAwaitable{};
cout << res << endl;
}
int main()
{
outer();
return 0;
}
Результат выполнения кода:
"inner done"
"abcde"