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();
}

看,是不是很简单呢,赶紧自己做一个吧!

原文链接: https://www.cnblogs.com/pointer-smq/p/12857426.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    C++20协程解糖 - 细节简化版

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/347262

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月2日 上午4:25
下一篇 2023年3月2日 上午4:26

相关推荐