最終更新日時: 2026年05月15日 13時53分21秒 (JST)
Akira Takahashi が更新

履歴 編集

class template
<ranges>

# std::ranges::as_input_view(C++26)

    namespace std::ranges {
      template<input_range V>
        requires view<V>
      class as_input_view : public view_interface<as_input_view<V>> { …… }; // (1)

      namespace views {
        inline constexpr /*unspecified*/ as_input = /*unspecified*/;          // (2)
      }
    }

## 概要

- (1): `input_range`として振る舞う`view`
- (2): `as_input_view`を生成するRangeアダプタオブジェクト

この`view`は、Rangeを`input_range`に変換し、非`common_range`にする (イテレータと番兵の型を別にする)。

この`view`は、パフォーマンス向上のために使用する。以下に例示する：

- `views::join(r)`は、`r`が`common_range` (イテレータと番兵の型が同じRange) である場合、イテレータと番兵の比較のために外側と内側の2種類のイテレータを順番に比較することになり比較コストが高くなる。`as_input`を使用することで、番兵との比較が一回で済むためにイテレータの比較コストが小さくなり、パフォーマンス向上が見込める
- `views::chunk`の場合、`r | views::chunk(n)`は`r`が`forward_range`以上である場合に各要素が`views::take(n)`となり、各要素を2回ずつイテレートすることになる。`input_range`に変換することで、各要素を1回ずつイテレートすることになり、パフォーマンス向上が見込める

### Rangeコンセプト

borrowed | sized | output | input | forward | bidirectional | random_access | contiguous | common | viewable | view
--- | --- | --- | --- | --- | --- | --- | --- | --- | --- | ---
※ | ※ |  | ○ |  |  |  | ※ |  | ○ | ○

- ※: `V`に従う

## 効果

- (2): 式`views::as_input(E)`の効果は次のいずれか（`T = decltype((E))`、`U = remove_cvref_t<T>`とする）
  - `T`が`input_range`のモデルであり、`common_range`を満たさず、`forward_range`も満たさない場合 : `views::all(E)`
  - それ以外の場合 : `as_input_view(E)`

## メンバ関数

名前 | 説明 | 対応バージョン
--- | --- | ---
`(constructor)` | コンストラクタ | C++26
`base` | `V`の参照を取得する | C++26
`begin` | 先頭を指すイテレータを取得する | C++26
`end` | 番兵を取得する | C++26
`size` | 要素数を取得する | C++26

## 継承しているメンバ関数

名前 | 説明 | 対応バージョン
--- | --- | ---
`empty` | Rangeが空かどうかを判定する | C++26
`operator bool` | Rangeが空でないかどうかを判定する | C++26
`front` | 先頭要素への参照を取得する | C++26
`back` | 末尾要素への参照を取得する | C++26
`operator[]` | 要素へアクセスする | C++26
`cbegin` | 定数イテレータを取得する | C++26
`cend` | 定数イテレータ（番兵）を取得する | C++26

## 推論補助

名前 | 説明 | 対応バージョン
--- | --- | ---
`(deduction_guide)` | クラステンプレートの推論補助 | C++26

## 例

### 基本的な使い方

    #include <ranges>
    #include <iostream>
    #include <vector>

    int main() {
      std::vector<int> v = {1, 2, 3, 4};

      for (auto i : v | std::views::as_input) {
        std::cout << i << ' ';
      }
    }

#### 出力

    1 2 3 4

### viewをパフォーマンス向上させる

    #include <ranges>
    #include <iostream>
    #include <vector>

    int main() {
      std::vector<std::vector<int>> v1 = {{1, 2}, {3, 4}};

     // `v1 | std::views::join`と比較して、イテレータと番兵の比較コストが低くなり、
     // パフォーマンスが向上する
      for (auto i : v1 | std::views::as_input | std::views::join) {
        std::cout << i << ' ';
      }

      // `v2 | std::views::chunk(3)`と比較して、各要素が1回ずつイテレートで済むため、
      // パフォーマンスが向上する
      std::vector v2 = {1, 2, 3, 4, 5, 6};
      for (const auto& v : v2 | std::views::as_input | std::views::chunk(3)) {
        for (const auto& i : v) {
          std::cout << i << ' ';
        }
        std::cout << std::endl;
      }
    }

#### 出力

    1 2 3 4 1 2 3
    4 5 6

## バージョン

### 言語

- C++26

### 処理系

- Clang: 21 ✅
- GCC: 15.1 ✅
- Visual C++: 2022 Update 14 ❌

## 参照

- P3137R3 `views::to_input`
- P3828R1 Rename the `to_input` view to `as_input`
  - `as_*`シリーズと一貫した命名にするため、`as_input`という名前に変更された