最終更新日時: 2026年06月09日 19時26分15秒 (JST)
yoh が更新

履歴 編集

class
<execution>

# std::execution::inline_scheduler(C++26)

    namespace std::execution {
      class inline_scheduler {
        class inline-sender; // exposition only
        template <receiver R>
        class inline-state;  // exposition only

      public:
        using scheduler_concept = scheduler_tag;

        constexpr inline-sender schedule() noexcept { return {}; }
        constexpr bool operator==(const inline_scheduler&) const noexcept = default;
      };
    }

## 概要

`inline_scheduler`は、インラインでタスクを実行するSchedulerである。

`schedule`操作により得られるSenderとReceiverを接続(connect)したOperationStateは、開始(start)したスレッド上で即座に値完了する。

戻り値型`task<T, E>`を持つタスクコルーチンのScheduler型として利用すると、コルーチン内で`co_await`式から再開(resume)時のスケジューリング操作を回避できる（動作詳細は`await_transform`を参照）。

## クラス仕様

`inline_scheduler`型の全オブジェクトは等しい。`inline_scheduler`型の部分式`sch`、クエリオブジェクト `q`、部分式のパック`args`としたとき、式`sch.query(q, args...)`は`inline-attrs<set_value_t>.query(q, args...)`と等価な式となる。

説明専用のクラス`inline-sender`を`sender`を満たす型とする。`completion_signatures_of_t<inline-sender>`は、`completion_signatures<set_value_t()>`となる。

説明用の`sndr`を`inline-sender`型の式とする。`CS`を`completion_signatures<set_value_t()>`としたとき、`rcvr`を`receiver-of<decltype((rcvr)), CS>`が`true`となる式とする。式`connect(sndr, rcvr)`の型は`inline-state<remove_cvref_t<decltype((rcvr))>>`であり、式`((void)sndr, auto(rcvr))`が潜在的に例外送出(potentially-throwing)するときに限って潜在的に例外送出する。

説明用の`o`を`inline-state<Rcvr>`型の非const左辺値とし、`REC(o)`を`o`を返す接続(connect)呼び出しへ渡した式`rcvr`で初期化された`Rcvr`型の非const左辺値参照とする。

- `REC(o)`が参照するオブジェクトは、`o`が参照するオブジェクトの生存期間(lifetime)で有効である。
- 式`start(o)`は、`set_value(std::move(REC(o)))`と等価。

### 説明専用クラステンプレート`inline-attrs`

    template<class Tag>
    struct inline-attrs {
      see below
    };

部分式`env`としたとき、`inline-attrs<Tag>{}.query(get_completion_scheduler<Tag>, env)`は`get_scheduler(env)`と等価な式となる。

部分式`env`としたとき、`inline-attrs<Tag>{}.query(get_completion_domain<Tag>, env)`は`get_domain(env)`と等価な式となる。

## メンバ関数

名前 | 説明 | 対応バージョン
--- | --- | ---
`(constructor)` | コンストラクタ | C++26
`(destructor)` | デストラクタ | C++26
`schedule` | スケジュールSenderを返す | C++26

## メンバ型

名前 | 説明 | 対応バージョン
--- | --- | ---
`scheduler_concept` | `scheduler_tag` | C++26

## 例

    #include <execution>
    #include <thread>
    #include <print>
    namespace ex = std::execution;

    // ex::task用のカスタム環境
    struct TaskEnv {
      using start_scheduler_type = ex::inline_scheduler;
    };

    ex::task<void> f(ex::scheduler auto sch)
    {
      std::println("step1 main#{}", std::this_thread::get_id());

      // スケジューラを変更してサブタスクを実行
      co_await (ex::schedule(sch) | ex::then([]{
        std::println("step2 worker#{}", std::this_thread::get_id());
      }));

      // デフォルト(task_scheduler)タスクコルーチンのco_await式では、
      // Scheduler Affinity動作により元のスケジューラ上で処理が継続する。
      std::println("step3 main#{}", std::this_thread::get_id());
    }

    ex::task<void, TaskEnv> g(ex::scheduler auto sch)
    {
      std::println("step1 main#{}", std::this_thread::get_id());

      // スケジューラを変更してサブタスクを実行
      co_await (ex::schedule(sch) | ex::then([]{
        std::println("step2 worker#{}", std::this_thread::get_id());
      }));

      // inline_schedulerを持つタスクコルーチンのco_await式では、
      // コルーチンの再開(resume)時に再スケジューリングが行われない。
      // このためco_await式内で変更したスケジューラが引き継がれる。
      std::println("step3 worker#{}", std::this_thread::get_id());
    }

    int main()
    {
      // ワーカースレッドを開始
      ex::run_loop loop;
      std::jthread worker{[&]{
        loop.run();
      }};
      auto sch = loop.get_scheduler();

      std::println("task_scheduler(default)");
      std::this_thread::sync_wait( f(sch) );

      std::println("inline_scheduler");
      std::this_thread::sync_wait( g(sch) );

      loop.finish();
    }

### 出力例

    task_scheduler(default)
    step1 main#124468393588544
    step2 worker#124468391311040
    step3 main#124468393588544
    inline_scheduler
    step1 main#124468393588544
    step2 worker#124468391311040
    step3 worker#124468391311040

## バージョン

### 言語

- C++26

### 処理系

- Clang: ??
- GCC: ??
- ICC: ??
- Visual C++: ??

## 関連項目

- `execution::scheduler`
- `execution::task`

## 参照

- P3552R3 Add a Coroutine Task Type
- P3826R5 Fix Sender Algorithm Customization
- P4159R0 Make `sender_in` and `receiver_of` exposition-only
- C++now 2025, Getting The Lazy Task Done