最終更新日時(UTC): 2025年08月31日 10時06分36秒
Raclamusi が更新

履歴 編集

class template
<ranges>

# std::ranges::zip_transform_view(C++23)

    namespace std::ranges {
      template<move_constructible F, input_range... Views>
        requires (view<Views> && ...) && (sizeof...(Views) > 0) && is_object_v<F> &&
                  regular_invocable<F&, range_reference_t<Views>...> &&
                  can-reference<invoke_result_t<F&, range_reference_t<Views>...>>
      class zip_transform_view : public view_interface<zip_transform_view<F, Views...>> { …… }; // (1)

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

## 概要

`zip_transform_view`は複数のRangeから要素を1つずつ取得し、それらを引数として関数を呼び出した結果を要素とする`view`。

`zip_transform_view`の要素を1つ取得するごとに、各Rangeの要素を1つずつ取得する。

zipするRangeのサイズが異なっている場合、`zip_transform_view`のサイズはそれらの中で最小のサイズとなる。

- (1): `zip_transform_view`のクラス定義
- (2): `zip_transform_view`を生成するカスタマイゼーションポイントオブジェクト(Rangeアダプタオブジェクトではない)

### Rangeコンセプト

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

- (1): `zip_view<Views...>`に従う

## 効果

- (2): `F`を部分式、`Es...`を部分式のパックとする。式 `views::zip_transform(F, Es...)` の効果は以下の通り。
  - `Es` が空でないとき、`zip_transform_view(F, Es...)` と等しい
  - `Es` が空のとき、 `FD` を `decay_t<decltype((F))>`として、`((void)F, auto(views::empty<decay_t<invoke_result_t<FD&>>>))` と等しい
    - ただし、 `move_constructible<FD> && regular_invocable<FD&>` が `false`、または `decay_t<invoke_result_t<FD&>>` がオブジェクト型でないとき、ill-formed

## メンバ関数

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

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

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

## 推論補助

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

## 例

    #include <ranges>
    #include <vector>
    #include <print>

    int main() {
      std::vector d = {1, 2, 3};
      std::vector p = {1, 10, 100, 1000};

      std::println("{}", std::views::zip_transform([](auto x, auto y){ return x * y; }, d, p));
      std::println("{}", std::views::zip_transform([](auto x, auto y){ return std::pair{x, y}; }, d, p));
    }

### 出力

    [1, 20, 300]
    [(1, 1), (2, 10), (3, 100)]

## バージョン

### 言語

- C++23

### 処理系

- Clang: 19 ✅
- GCC: 13 ✅
- Visual C++: 2022 Update 6 ✅

## 関連項目

- `transform_view` zipする範囲が1つの場合
- `transform` 2つのRangeから要素を1つずつ取り出して関数を呼び出し、結果を出力するアルゴリズム関数

## 参照

- N4950 26 Ranges library
- P2321R2 zip