C++20协程解糖 - 细节简化版
我已经花了10分钟完全了解了C++20协程!
如果你看到这行文字,说明这篇文章被无耻的盗用了(或者你正在选中文字),请前往 cnblogs.com/pointer-smq 支持原作者,谢谢
这篇文章仅展示简化版的控制流解糖,不展示coroutine_handle和各种awaitable的内部实现
被简化掉的部分包括异常处理,传参,await_transform,operator await和new的额外参数
//原
future<int> func1() {
int result = 0;
for (int i = 0; i < 10; i++) {
result += co_await func2();
}
co_return result;
}
int main() {
auto f = func1();
//故意不await,仅展示调用
}
解糖之后
//解糖
struct __func1_state : future<int>::promise_type
{
int __resume_state = 0;
int __local_result;
int __local_i;
any __curr_await; // any只是一个概念上的,就表示这里可能装任何awaitable
void __move_next() {
__LABEL_START:
switch (__resume_state) {
case 0: {//initial suspension point
__curr_await = this->initial_suspend(); //from promise_type
__resume_state = 1;
break; //开始await initial_suspend
}
case 1: { //initial suspend后, for的初始化部分
__curr_await.await_resume(); //initial resume
__local_result = 0;
__local_i = 0;
[[fallthrough]];
}
case 2: { //for的co_await前半部分
if (__local_i < 10) {
__curr_await = __func2_thunk(); //co_await func2的地方
__resume_state = 3;
break; //开始await func2返回的future
} else { //for结束
__resume_state = 4;
goto __LABEL_START;
}
}
case 3: { //for的co_await后半部分
__local_result += __curr_await.await_resume(); //result += co_await的地方
__local_i++;
__resume_state = 2;
goto __LABEL_START;
}
case 4: { //co_return
this->return_value(__local_result); //from promise_type
__curr_await = this->final_suspend();
__resume_state = 5;
break; //开始await final_suspend
}
case 5: { //final suspend返回
__curr_await.await_resume();
this->destroy(); //from coroutine_handle
return; //协程结束,销毁自己,delete this
}
} //end switch
// 开始 await __curr_await,上面算出来的
if (__curr_await.await_ready()) {
goto __LABEL_START;
} else {
auto r = __curr_await.await_suspend(coroutine_handle<int>{this});//coroutine_handle就是一个裸指针的简单包装
if constexpr (r instance of bool) {
if (!r) {
goto __LABEL_START;
}
} else if constexpr (r instance of coroutine_handle) {
r.resume();
}
return; //真的暂停协程
}
}
};
future<int> __func1_thunk() {
__func1_state* state = new __func1_state();
future<int> ret = state->get_return_object(); //from promise_type
state.__move_next();
return ret;
}
int main() {
auto f = __func1_thunk();
}
看,是不是很简单呢,赶紧自己做一个吧!