c++20中的协程(coroutines)怎么用_c++20协程使用方法

C++20协程通过co_await、co_yield、co_return实现暂停与恢复,用于异步编程和生成器;需定义含promise_type的返回类型,控制初始、最终挂起及返回行为;示例展示整数生成器和异步等待的实现机制。

c++20中的协程(coroutines)怎么用_c++20协程使用方法

C++20 引入了协程(Coroutines),它是一种可以暂停和恢复执行的函数,适用于异步编程、生成器、任务调度等场景。协程不是线程,它运行在当前线程中,通过 co_awaitco_yieldco_return 来标记一个函数为协程。

1. 判断一个函数是协程

只要函数体内包含以下任意一个关键字,编译器就会将其视为协程:

co_await:等待一个可等待对象(awaiter)co_yield:产生一个值并暂停co_return:结束协程并返回结果

例如:

#include #include 

struct [[nodiscard]] task {struct promise_type {task get_return_object() { return {}; }std::suspend_never initial_suspend() { return {}; }std::suspend_never final_suspend() noexcept { return {}; }void return_void() {}void unhandled_exception() {}};};

task my_coroutine() {std::cout << "协程开始n";co_await std::suspend_always{};std::cout << "协程恢复n";co_return;}

2. 协程的核心组件

要使用协程,必须定义一个返回类型,该类型包含嵌套的 promise_type。这个结构决定了协程的行为。

立即学习“C++免费学习笔记(深入)”;

常见成员函数包括:

get_return_object():创建并返回协程句柄关联的对象initial_suspend():协程启动时是否暂停(std::suspend_always 暂停,std::suspend_never 不暂停)final_suspend():协程结束时是否暂停return_void()return_value(T):处理 co_returnunhandled_exception():异常处理

3. 使用 co_yield 实现生成器

常见用途之一是实现惰性生成器。下面是一个简单的整数生成器示例:

#include #include #include 

templatestruct generator {struct promisetype {T value;generator get_return_object() { return generator{this}; }std::suspend_always initial_suspend() { return {}; }std::suspend_always final_suspend() noexcept { return {}; }std::suspend_always yieldvalue(T value) {value = value;return {};}void return_void() {}void unhandled_exception() { std::terminate(); }};

using handle_type = std::coroutine_handle;explicit generator(promise_type* p)    : coro_(handle_type::from_promise(*p)) {}~generator() { if (coro_) coro_.destroy(); }bool move_next() {    if (!coro_ || coro_.done()) return false;    coro_.resume();    return !coro_.done();}T current_value() const { return coro_.promise().value_; }

private:handletype coro;};

generator range(int from, int to) {for (int i = from; i

int main() {for (auto g = range(1, 6); g.move_next();) {std::cout

输出:

1 2 3 4 5

4. 使用 co_await 实现异步等待

你可以定义自己的可等待类型,实现异步操作的挂起与恢复。

struct suspend_immediate {    bool await_ready() { return false; } // 立即挂起    void await_suspend(std::coroutine_handle h) {        std::cout << "协程被挂起,即将恢复...n";        h.resume(); // 立即恢复(可用于调度)    }    void await_resume() {}};

generator async_example() {std::cout << "第一步n";co_await suspend_immediate{};std::cout << "第三步n";}

这段代码会依次输出:

第一步
协程被挂起,即将恢复...
第三步

说明协程在 co_await 处暂停,并由 await_suspend 控制何时恢复。

基本上就这些。C++20 协程底层灵活但需要手动封装,建议结合现有库如 cppcoroBoost.Asio 来简化使用。不复杂但容易忽略细节。

以上就是c++++20中的协程(coroutines)怎么用_c++20协程使用方法的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1477645.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月19日 02:12:50
下一篇 2025年12月19日 02:12:58

相关推荐

  • c++中的std::weak_ptr有什么用_c++ std::weak_ptr使用方法

    std::weak_ptr用于解决std::shared_ptr的循环引用问题,它不增加引用计数,可安全检查对象是否存在。通过从shared_ptr创建weak_ptr,并使用lock()方法获取临时shared_ptr来判断对象是否有效,从而避免内存泄漏。 std::weak_ptr 是 C++ …

    2025年12月19日
    000
  • c++怎么用g++编译时链接一个库_c++ g++库链接方法

    使用g++链接外部库需用-L指定库路径,-l指定库名(无需lib前缀和扩展名),同时用-I包含头文件路径;优先链接动态库.so,也可直接提供静态库.a完整路径;确保库命名规范并设置LD_LIBRARY_PATH以防运行时找不到.so文件。 在使用 g++ 编译 C++ 程序时,如果需要调用外部库(如…

    2025年12月19日
    000
  • C++如何判断一个指针是否为空_C++ 指针空判断方法

    使用nullptr判断指针是否为空最安全,推荐替代NULL或0;2. 动态分配后需检查返回指针是否为nullptr以处理分配失败;3. 函数传参时应先判断指针参数是否为空避免解引用空指针。 在C++中判断一个指针是否为空,最直接的方法是将其与nullptr进行比较。空指针表示该指针没有指向任何有效的…

    2025年12月19日
    000
  • c++中如何实现移动构造函数_c++移动构造函数实现方法

    移动构造函数通过右值引用高效转移资源,避免深拷贝。其语法为T(T&&),需将源对象资源接管并置为nullptr,防止重复释放;建议标记noexcept以提升性能。编译器仅在未定义析构或拷贝操作时自动生成移动构造,否则需手动实现。例如Buffer类中,移动构造接管ptr与size,并清…

    2025年12月19日
    000
  • c++ shared_ptr和unique_ptr怎么选择_c++ 智能指针选择方法

    选择std::unique_ptr还是std::shared_ptr取决于是否需要共享所有权。若资源仅由单一方独占使用,优先选用std::unique_ptr,因其无运行时开销且安全高效;若多个对象或模块需共享同一资源,则使用std::shared_ptr,但需注意引用计数带来的性能成本及潜在循环引…

    2025年12月19日
    000
  • c++怎么理解RAII原则_c++ RAII原则解析

    RAII通过对象生命周期管理资源,利用构造函数获取资源、析构函数释放资源,确保异常安全和资源不泄漏。 RAII(Resource Acquisition Is Initialization)即“资源获取即初始化”,是C++中一种重要的编程思想,核心在于通过对象的生命周期来管理资源。它不是语言语法的一…

    2025年12月19日
    000
  • c++怎么实现一个线程池_c++线程池实现方法

    答案:C++线程池通过复用线程执行任务,核心包含任务队列、线程集合、互斥锁、条件变量和运行控制开关。工作线程循环等待任务,任务以std::function封装存入队列,通过enqueue添加任务并通知线程,析构时设置停止标志并等待所有线程完成。需注意异常处理、避免阻塞及禁止在关闭后添加任务。 在C+…

    2025年12月19日
    000
  • C++如何重载运算符_C++ 运算符重载方法

    运算符重载是C++中通过函数重载为自定义类型赋予标准运算符新含义的机制,提升代码可读性。它要求至少一个操作数为用户自定义类型,不改变运算符优先级和结合性。可通过成员函数(左侧操作数为this)或全局函数(支持对称操作,常用于+、 在C++中,运算符重载是一种允许自定义类型(如类或结构体)使用标准运算…

    2025年12月19日
    000
  • c++如何判断一个文件是否存在_c++ 文件存在判断方法

    c++kquote>答案:C++中判断文件是否存在常用方法包括std::ifstream、C++17的std::filesystem::exists和POSIX的access函数;推荐优先使用std::filesystem::exists,若不支持则可选std::ifstream或跨平台acc…

    2025年12月19日
    000
  • c++中如何使用constexpr常量_c++ constexpr常量定义方法

    constexpr用于声明编译时常量或函数,要求值在编译期确定,适用于数组大小、模板参数等场景;其变量需用常量表达式初始化,如constexpr int size = 10;不能使用运行时变量初始化,如constexpr int y = x(x为变量)错误;constexpr函数在传入常量表达式时可…

    2025年12月19日 好文分享
    000
  • c++中如何传递数组给函数_c++数组传参方法

    答案:C++中数组传参常用指针或引用。1. 指针传递:数组自动退化为指向首元素的指针,如void printArray(int* arr, int size)。 在C++中,数组不能以值的方式整体传递给函数,但可以通过几种方式将数组传入函数。最常见的是通过指针或引用传递。下面介绍几种常用的方法。 1…

    2025年12月19日
    000
  • C++如何实现UDP通信_C++ UDP通信实现方法

    C++中实现UDP通信需创建套接字、绑定地址、收发数据并关闭资源。首先调用socket函数创建UDP套接字,接收方使用bind绑定IP与端口,通过sendto发送数据,recvfrom接收数据,最后根据平台调用close或closesocket关闭套接字,Windows需初始化及清理Winsock库…

    2025年12月19日
    000
  • c++中如何判断链表是否有环_c++链表环检测方法

    使用快慢指针可高效判断链表是否有环,时间复杂度O(n),空间复杂度O(1);当快慢指针相遇后,将一指针移回头节点并同步前进,再次相遇点即为环入口。 判断链表是否有环是常见的数据结构问题。在C++中,最高效的方法是使用快慢指针(Floyd判圈法)。这种方法不需要额外的存储空间,时间复杂度为O(n),空…

    2025年12月19日
    000
  • C++如何使用auto关键字简化代码_C++ auto关键字使用方法

    auto关键字在C++11中用于自动推导变量类型,简化复杂类型声明,如auto it = vec.begin();结合范围for循环可减少模板容器遍历代码量,支持const auto&避免拷贝,配合尾置返回类型和Lambda表达式实现高效简洁的泛型编程,但应避免在类型明显时滥用以保持可读性。…

    2025年12月19日
    000
  • c++20中的范围库(Ranges)怎么用_c++20 Ranges使用方法

    C++20 Ranges简化了容器操作,无需显式迭代器,支持链式视图与惰性求值。通过ranges::sort直接排序,views::filter过滤、views::transform映射、views::take取前n个元素,可组合成清晰管道。例如筛选偶数并平方取前三:4 16 36;处理map时可用…

    2025年12月19日
    000
  • c++怎么实现装饰器模式_c++装饰器模式实现方法

    装饰器模式通过组合动态扩展对象功能,C++中定义Component基类,ConcreteComponent实现基础功能,Decorator持有Component指针,ConcreteDecorator在调用前后添加新行为,支持多层叠加,示例中decoratedAB依次执行B前置、A前置、基础功能、A…

    2025年12月19日
    000
  • c++如何调用系统命令_c++执行系统命令方法

    使用std::system()可执行系统命令,需包含cstdlib头文件,传入命令字符串,返回值表示执行结果。示例:Linux下用”ls -l”列出文件,Windows下用”dir”。返回0表示成功,非0表示失败,可用于判断命令执行状态。注意跨平台命令…

    2025年12月19日
    000
  • c++怎么模拟鼠标和键盘事件_c++鼠标键盘事件模拟方法

    使用SendInput可模拟鼠标键盘事件,先设置INPUT结构体类型与参数,再调用SendInput发送按键或鼠标动作,支持组合键与精确控制,需注意键码、标志位及焦点问题。 在C++中模拟鼠标和键盘事件,通常用于自动化操作、游戏外挂或测试工具开发。Windows平台提供了系统级别的API来实现这些功…

    2025年12月19日
    000
  • c++怎么编写Google Test单元测试_c++ Google Test单元测试方法

    首先安装配置Google Test,接着编写被测函数和测试用例,然后通过CMake构建项目并运行测试。具体步骤包括:使用包管理器或源码安装gtest,定义待测函数如add,利用TEST宏创建测试套件与用例,使用EXPECT_EQ进行断言,在CMakeLists.txt中配置gmock_main或GT…

    2025年12月19日 好文分享
    000
  • c++怎么判断系统是32位还是64位_c++系统位数判断方法

    可通过预定义宏或指针大小判断系统位数。首先使用_WIN64、__x86_64__等宏在编译期识别,示例代码输出“系统位数: 64位”或“32位”;其次利用sizeof(void*)为8或4字节判断运行时架构;推荐结合宏与类型大小提升跨平台兼容性,适用于多数C++项目。 在C++中判断系统是32位还是…

    2025年12月19日
    000

发表回复

登录后才能评论
关注微信