std:: coroutine_traits
      From cppreference.net
     
     
     
        
         C++
        
        
         
          
           
          
          
         
        
       
       
        
         Utilities library
        
        
         
          
           
            
          
          
          
         
        
       
       | 
 | 
 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
        
         Coroutine support
        
        
         
          
           
            
          
          
          
         
        
       
       | Coroutine traits | ||||
| 
                
                 
                  
                   coroutine_traits
                  
                 
                
                
                
                 
                  
                   (C++20)
                  
                 
                
                | ||||
| Coroutine handle | ||||
| 
                
                 
                  
                   (C++20)
                  
                 
                
                | ||||
| No-op coroutines | ||||
| 
                
                 
                  
                   (C++20)
                  
                 
                
                | ||||
| 
                
                 
                  
                   (C++20)
                  
                 
                
                | ||||
| Trivial awaitables | ||||
| 
                
                 
                  
                   (C++20)
                  
                 
                
                | ||||
| 
                
                 
                  
                   (C++20)
                  
                 
                
                | ||||
| Range generators | ||||
| 
                
                 
                  
                   (C++23)
                  
                 
                
                | 
| 
           定义于头文件
            
            
             <coroutine>
            
            | ||
| 
           
            
             template
            
            
             <
            
            
             class
            
            R,
            
             class
            
            ...
            
             Args
            
            
             >
            
             struct coroutine_traits ; | (C++20 起) | |
       从协程的返回类型和参数类型确定承诺类型。标准库实现提供一个公开可访问的成员类型
       
        promise_type
       
       ,当该限定标识符有效且表示类型时,该成员类型与
       
        R::promise_type
       
       相同。否则,不存在此成员类型。
      
       
        程序定义的特化
       
       必须定义一个可公开访问的嵌套类型
       
        promise_type
       
       ,否则程序非良构。
      
| 目录 | 
模板参数
| R | - | 协程的返回类型 | 
| Args | - | 协程的参数类型,包括 隐式对象参数 (当协程为非静态成员函数时) | 
嵌套类型
| 名称 | 定义 | 
| 
          promise_type
          | 若有效则为 
          R::promise_type
         ,否则由程序定义的特化提供 | 
可能的实现
| namespace detail { template<class, class...> struct coroutine_traits_base {}; template<class R, class... Args> requires requires { typename R::promise_type; } struct coroutine_traits_base <R, Args...> { using promise_type = R::promise_type; }; } template<class R, class... Args> struct coroutine_traits : detail::coroutine_traits_base<R, Args...> {}; | 
注释
       如果协程是非静态成员函数,那么
       
        Args...
       
       中的第一个类型是隐式对象参数的类型,其余的是函数的参数类型(如果有的话)。
      
       如果
       
        std::coroutine_traits<R, Args...>::promise_type
       
       不存在或不是类类型,则对应的协程定义是非法的。
      
       用户可依据程序定义类型定义
       
        coroutine_traits
       
       的显式或偏特化,以避免修改返回类型。
      
示例
         运行此代码
        
       #include <chrono> #include <coroutine> #include <exception> #include <future> #include <iostream> #include <thread> #include <type_traits> // 下面特化的 coroutine_traits 所依赖的程序定义类型 struct as_coroutine {}; // 通过使用 std::promise<T> 作为 promise 类型,启用 std::future<T> 作为协程类型 template<typename T, typename... Args> requires(!std::is_void_v<T> && !std::is_reference_v<T>) struct std::coroutine_traits<std::future<T>, as_coroutine, Args...> { struct promise_type : std::promise<T> { std::future<T> get_return_object() noexcept { return this->get_future(); } std::suspend_never initial_suspend() const noexcept { return {}; } std::suspend_never final_suspend() const noexcept { return {}; } void return_value(const T& value) noexcept(std::is_nothrow_copy_constructible_v<T>) { this->set_value(value); } void return_value(T&& value) noexcept(std::is_nothrow_move_constructible_v<T>) { this->set_value(std::move(value)); } void unhandled_exception() noexcept { this->set_exception(std::current_exception()); } }; }; // 对 std::future<void> 同理。 template<typename... Args> struct std::coroutine_traits<std::future<void>, as_coroutine, Args...> { struct promise_type : std::promise<void> { std::future<void> get_return_object() noexcept { return this->get_future(); } std::suspend_never initial_suspend() const noexcept { return {}; } std::suspend_never final_suspend() const noexcept { return {}; } void return_void() noexcept { this->set_value(); } void unhandled_exception() noexcept { this->set_exception(std::current_exception()); } }; }; // 允许通过简单地为每个 co_await 生成新线程来 co_await std::future<T> 和 std::future<void> template<typename T> auto operator co_await(std::future<T> future) noexcept requires(!std::is_reference_v<T>) { struct awaiter : std::future<T> { bool await_ready() const noexcept { using namespace std::chrono_literals; return this->wait_for(0s) != std::future_status::timeout; } void await_suspend(std::coroutine_handle<> cont) const { std::thread([this, cont] { this->wait(); cont(); }).detach(); } T await_resume() { return this->get(); }