netcan/asyncio

关于task.h中的await_transform和co_await如何执行

Closed this issue · 2 comments

co_await expr会被转化为

auto&& awaitable = **get_awaitable**(promise, static_cast<decltype(value)>(value));
auto&& awaiter = get_awaiter(static_cast<decltype(awaitable)>(awaitable));

而get_awaitable由下面伪代码构成

decltype(auto) **get_awaitable**(P& promise, T&& expr)
{
  if constexpr (has_any_await_transform_member_v<P>)
    return promise.await_transform(static_cast<T&&>(expr));
  else
    return static_cast<T&&>(expr);
}

参考task_test.cpp例子,struct Task不应该是一个awaitable对象,想问一下task.h中的await_transform是如何工作的。
调试代码,先运行await_transform再运行co_await,没弄明白参数是怎么传递的,能否做个简单提示
不胜感激

co_await task为例,由于Task类的Promise定义了await_transform函数,因此会调用

auto task_awaiter = p. await_transform(task);

因为我的await_transform只是简单地透传一下task,所以

auto task_awaiter = task;

接下来就是调用task对象的operator co_await操作符拿到真正的awaiter,编译器会展开awaiter里的await_ready/await_suspend/await_resume等函数。

感兴趣的话可以参考一下我的书,机工社《C++20高级编程》:
image

co_await task为例,由于Task类的Promise定义了await_transform函数,因此会调用

auto task_awaiter = p. await_transform(task);

因为我的await_transform只是简单地透传一下task,所以

auto task_awaiter = task;

接下来就是调用task对象的operator co_await操作符拿到真正的awaiter,编译器会展开awaiter里的await_ready/await_suspend/await_resume等函数。

await_transform仅是透传,concepts::Awaitable的require要求Task重载co_await,operator co_await操作符拿到真正的awaiter,明白了谢谢指教,另书已买还没到