最終更新日時: 2026年07月22日 16時08分23秒 (JST)
rotarymars が更新

履歴 編集

customization point object
<execution>

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

    namespace std::execution {
      template<class CPO>
      struct get_completion_scheduler_t { unspecified };

      template<class CPO>
      constexpr get_completion_scheduler_t<CPO> get_completion_scheduler{};
    }

## 概要

`get_completion_scheduler<completion-tag>`は、Senderの属性から指定完了タグに関連付けられた完了Schedulerを取得するクエリオブジェクトである。

コア定数式`forwarding_query(get_completion_scheduler<completion-tag>)`は`true`値を返す。

### 完了Scheduler

完了Scheduler(completion scheduler)は、非同期操作の完了操作を実行するための実行リソース（例：CPUスレッド）と関連付けられたSchedulerである。

非同期操作の完了操作は、下記いずれかの完了関数呼び出しが該当する。

- 値完了関数 `execution::set_value`
- エラー完了関数 `execution::set_error`
- 停止完了関数 `execution::set_stopped`

## 効果

`completion-fn`を完了関数、`completion-tag`を完了関数に関連付けられた完了タグ、`args`と`envs`を部分式のパック、式`sndr`を`sender<decltype((sndr))>`が`true`かつ`get_completion_scheduler<completion-tag>(get_env(sndr), envs...)`となる式、`sch`をSchedulerとする。

式`sch1`とパック`envs`に対して、式`sch2`を`TRY-QUERY(sch, get_completion_scheduler<completion-tag>, envs...)`とする。`sch2`が不適格もしくは`sch1`と`sch2`が同一型かつ等しいとき、式`RECURSE-QUERY(sch1, envs...)`を`sch1`と等価な式とする。そうでなければ、式`RECURSE-QUERY(sch2, envs...)`と透過な式とする。

式`q`とパック`envs`に対して、完了タグ`completion-tag`が`set_value_t`／`set_error_t`／ `set_stopped_t`のいずれでもなければ、呼び出し式`get_completion_scheduler<completion-tag>(q, envs...)`は不適格となる。 そうでなければ、呼び出し式は下記と等価。

- `envs...`が1回だけ評価されることを除いて、適格ならば下記の式

      MANDATE-NOTHROW(RECURSE-QUERY(
        TRY-QUERY(q, get_completion_scheduler<completion-tag>, envs...), envs...))

- そうではなく、`envs...`が1回だけ評価されることを除いて、型`q`が`scheduler`を満たしかつ`envs`が空のパックでないとき、`auto(q)`

- そうでなければ、呼び出し式`get_completion_scheduler<completion-tag>(q, envs...)`は不適格となる。

`get_completion_scheduler<completion-tag>(q, envs...)`が適格ならば、その型はSchedulerを満たすべき。

## 例外

投げない

## カスタマイゼーションポイント

const修飾クエリ可能オブジェクト `cq`に対して式`cq.query(get_completion_scheduler<completion-tag>)`が呼び出される。 このとき、`noexcept(cq.query(get_completion_scheduler<completion-tag>)) == true`であること。

型`Tag`、式`sndr`、パック`envs`に対して、`CS`を`completion_signatures_of_t<decay_t<decltype((sndr))>, decltype((envs))...>`とする。`get_completion_scheduler<Tag>(get_env(sndr), envs...)`と`CS`が両者とも適格、かつ`CS().count-of(Tag()) == 0`が`true`のとき、プログラムは不適格となる。

`sndr`とReceiver `rcvr`を接続して作成された非同期操作が完了関数`completion-fn(rcvr, args...)`を評価するとき、その評価が`sch`と関連付けられた実行リソースの実行エージェント上で行われない場合、動作は未定義となる。

## 例

    #include <execution>
    #include <cassert>
    namespace ex = std::execution;

    int main()
    {
      ex::run_loop loop;
      ex::scheduler auto loop_sch = loop.get_scheduler();

      // schedule(loop_sch)の完了Schedulerはloop_schに等しい
      ex::sender auto snd0 = ex::schedule(loop_sch);
      auto sch0 = ex::get_completion_scheduler<ex::set_value_t>(ex::get_env(snd0));
      assert(sch0 == loop_sch);

      // 完了Schedulerは接続されたSenderへと引き継がれる
      ex::sender auto snd1 = snd0 | ex::then([]{ return 42; });
      auto sch1 = ex::get_completion_scheduler<ex::set_value_t>(ex::get_env(snd1));
      assert(sch1 == loop_sch);

    #if 0
      // just Senderは完了Schedulerを持たない
      ex::sender auto snd2 = ex::just(42);
      auto sch2 = ex::get_completion_scheduler<ex::set_value_t>(ex::get_env(snd2));
    #endif
    }

### 出力

## バージョン

### 言語

- C++26

### 処理系

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

## 関連項目

- `execution::scheduler`
- `execution::schedule`
- `execution::set_value`
- `execution::set_error`
- `execution::set_stopped`

## 参照

- P2300R10 `std::execution`
- P3826R5 Fix Sender Algorithm Customization