• Class / Function / Type

      std::
    • Header file

      <>
    • Other / All

    最終更新日時(UTC):
    が更新

    履歴 編集

    class template
    <coroutine>

    std::coroutine_handle

    namespace std {
      template<class Promise = void>
      struct coroutine_handle;
    
      template<>
      struct coroutine_handle<void> {
        // (メンバ宣言は省略)
      };
    
      template<class Promise>
      struct coroutine_handle {
        // (メンバ宣言は省略)
      };
    }
    

    概要

    コルーチンに対応するコルーチンハンドル。 テンプレートパラメータPromiseには、コルーチンのPromise型を指定する。

    コルーチンハンドルはアプリケーションコードからの直接アクセスを想定した機能ではなく、コルーチンライブラリ提供クラス内部に隠蔽される構造が一般的である。 例: 後述サンプルコードではtaskクラス内に隠蔽されており、コルーチンfや関数mainから間接的に利用される。

    coroutine_handle<void>または単にcoroutine_handle<>は、Promise型について型消去(Type-erased)されたコルーチンハンドルとして取り扱える。 コルーチンのPromise型を明示したcoroutine_handle<Promise>からcoroutine_handle<>へと暗黙変換が可能となっている。

    C++コルーチンとC API(コールバック関数へのポインタとvoid*をとる関数)との組合せ利用を可能とするため、coroutine_handleとポインタ型void*との相互変換がサポートされる。

    ユーザプログラムがcoroutine_handleの明示特殊化または部分特殊化を宣言した場合、その動作は未定義とされる。

    メンバ関数

    構築・リセット

    名前 説明 対応バージョン
    (constructor) コンストラクタ C++20
    operator= 代入演算子 C++20

    エクスポート

    名前 説明 対応バージョン
    address コルーチンハンドルに対応するアドレス値 C++20

    変換

    名前 説明 対応バージョン
    operator coroutine_handle<> 型消去されたコルーチンハンドルを返す C++20

    観測

    名前 説明 対応バージョン
    operator bool 有効なコルーチンか確認 C++20
    done 最終サスペンドポイントで中断状態にあるか確認 C++20

    再開

    名前 説明 対応バージョン
    operator() 中断状態にあるコルーチンを再開 C++20
    resume 中断状態にあるコルーチンを再開 C++20
    destroy 中断状態にあるコルーチンを破棄 C++20

    Promiseアクセス

    名前 説明 対応バージョン
    promise Promiseオブジェクトの参照(coroutine_handle<Promise>のみ) C++20

    静的メンバ関数

    名前 説明 対応バージョン
    from_promise Promiseオブジェクトから対応するコルーチンハンドルへ変換(coroutine_handle<Promise>のみ) C++20
    from_address アドレス値から対応するコルーチンハンドルへ変換 C++20

    非メンバ関数

    ハッシュサポート

    名前 説明 対応バージョン
    template<class T> struct hash 先行宣言(class template) C++20
    template<class P> struct hash<coroutine_handle<P>> hashcoroutine_handle<P>に対する特殊化 C++20

    比較演算子

    名前 説明 対応バージョン
    bool operator==(coroutine_handle<>, coroutine_handle<>); 等値比較 C++20
    bool operator!=(coroutine_handle<>, coroutine_handle<>); 非等値比較 (==により使用可能) C++20
    strong_ordering operator<=>(coroutine_handle<>, coroutine_handle<>); 三方比較 C++20
    bool operator<(coroutine_handle<>, coroutine_handle<>); 左辺が右辺より小さいかを判定する (<=>により使用可能) C++20
    bool operator<=(coroutine_handle<>, coroutine_handle<>); 左辺が右辺以下を判定する (<=>により使用可能) C++20
    bool operator>(coroutine_handle<>, coroutine_handle<>); 左辺が右辺より大きいかを判定する (<=>により使用可能) C++20
    bool operator>=(coroutine_handle<>, coroutine_handle<>); 左辺が右辺以上かを判定する (<=>により使用可能) C++20

    coroutine_handle同士の比較は、addressが返すアドレス値を用いて比較演算が行われる。

    #include <coroutine>
    #include <iostream>
    #include <utility>
    
    struct task {
      struct promise_type {
        int value_;
        auto get_return_object() { return task{*this}; }
        auto initial_suspend() { return std::suspend_never{}; }
        auto final_suspend() noexcept { return std::suspend_always{}; }
        void return_value(int x) { value_ = x; }
        void unhandled_exception() { std::terminate(); }
      };
    
      ~task()
      {
        if (coro_)
          coro_.destroy();
      }
    
      task(task const&) = delete;
      task(task&& rhs)
        : coro_(std::exchange(rhs.coro_, nullptr)) {}
    
      int get()
      {
        if (!coro_.done()) {
          coro_.resume();
        }
        return coro_.promise().value_;
      }
    
    private:
      explicit task(promise_type& p)
        : coro_(std::coroutine_handle<promise_type>::from_promise(p)) {}
    
      std::coroutine_handle<promise_type> coro_;
    };
    
    task f()
    {
      std::cout << "coroutine" << std::endl;
      co_return 42;
    }
    
    int main()
    {
      auto c = f();
      std::cout << "main" << std::endl;
      int r = c.get();
      std::cout << "result=" << r << std::endl;
    }
    

    出力

    coroutine
    main
    result=42
    

    バージョン

    言語

    • C++20

    処理系

    関連項目

    参照