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

履歴 編集

class template
<ranges>

# std::ranges::elements_view(C++20)

    namespace std::ranges {
      template<input_range V, size_t N>
        requires view<V> && has-tuple-element<range_value_t<V>, N> &&
                 has-tuple-element<remove_reference_t<range_reference_t<V>>, N>
      class elements_view : public view_interface<elements_view<V, N>> { …… }; // (1)

      template<class R>
      using keys_view = elements_view<views::all_t<R>, 0>;                     // (2)

      template<class R>
      using values_view = elements_view<views::all_t<R>, 1>;                   // (3)

      namespace views {
        template<size_t N>
        inline constexpr /*unspecified*/ elements = /*unspecified*/;           // (4)

        inline constexpr auto keys = elements<0>;                              // (5)

        inline constexpr auto values = elements<1>;                            // (6)
      }
    }

## 概要

タプルと見なせる型を要素とするRangeに対して、各タプルの第N要素だけにアクセスする`view`。要素へのアクセスは`get<N>`による。

- (1): 第N要素だけにアクセスする`view`
- (2): 第1要素だけにアクセスする`view`
- (3): 第2要素だけにアクセスする`view`
- (4): `elements_view`を生成するRangeアダプタオブジェクト
- (5): `keys_view`を生成するRangeアダプタオブジェクト
- (6): `values_view`を生成するRangeアダプタオブジェクト

### Rangeコンセプト

borrowed | sized | output | input | forward | bidirectional | random_access | contiguous | common | viewable | view
--- | --- | --- | --- | --- | --- | --- | --- | --- | --- | ---
(1) | (1) | (1) | (1) | (1) | (1) | (1) |  | (1) | ○ | ○

- (1): `V`に従う

## テンプレートパラメータ制約

説明専用コンセプト`has-tuple-element`を次のように定義する。

    // C++20
    template<class T, size_t N>
    concept has-tuple-element =
      requires(T t) {
        typename tuple_size<T>::type;
        requires N < tuple_size_v<T>;
        typename tuple_element_t<N, T>;
        { get<N>(t) } -> convertible_to<const tuple_element_t<N, T>&>;
      };

    // C++23
    template<class T, size_t N>
    concept has-tuple-element =
      tuple-like<T> && N < tuple_size_v<T>;

これを用いて、

- `view<V>`
- `input_range<V>`
- `has-tuple-element<range_value_t<V>, N>`
- `has-tuple-element<remove_reference_t<range_reference_t<V>>, N>`

## 効果

- (4): `E`を部分式、`N`を定数式とするとき、式`views::elements<N>(E)`の効果は`elements_view<views::all_t<decltype((E))>, N>{E}`と等しい。

## メンバ関数

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

`r`を元のRangeとする。`size`は`ranges::size(r)`が有効な式であるときに定義される。

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

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

## 推論補助

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

## 例

    #include <ranges>
    #include <map>
    #include <string>
    #include <iostream>

    int main() {
      std::map<int, std::string> m = {{1, "one"}, {2, "two"}, {3, "three"}};

      for (int i : m | std::views::keys) {
        std::cout << i << '\n';
      }

      for (const std::string& i : m | std::views::values) {
        std::cout << i << '\n';
      }
    }

### 出力

    1
    2
    3
    one
    two
    three

## バージョン

### 言語

- C++20

### 処理系

- Clang: 13.0.0 ✅
- GCC: 10.1.0 ✅
- ICC: ?
- Visual C++: 2019 Update 10 ✅

## 関連項目

- `zip_view` elements_viewの逆(要素からタプルを作る)

## 参照

- N4861 24 Ranges library
- C++20 ranges
- P2165R4 Compatibility between `tuple`, `pair` and tuple-like objects
- P2017R1 Conditionally borrowed ranges