【C++】views::zip で複数のコンテナを同時にループさせる方法

目次

はじめに

プログラミングでは、「商品IDのリスト」「商品名のリスト」「価格のリスト」のように、それぞれ別のコンテナに格納されているものの、インデックス番号が対応している複数のリストを同時に扱いたい、という場面が頻繁にあります。

従来、このような処理は、for(int i = 0; ...) のように、手動でインデックスカウンターを使ったforループで記述する必要がありました。

この問題をエレガントに解決するのが、C++23で導入された std::views::zip です。このレンジアダプタは、複数のコンテナを「圧縮(zip)」し、各コンテナの同じインデックスにある要素をペア(タプル)として、一度にループで取り出すことを可能にします。


【前提】C++23とは?

C++23(シーピープラスにーさん)は、2023年に正式化された、C++言語の比較的新しい規格です。std::views::zip はこのC++23で追加された機能のため、利用するにはC++23に対応した最新のコンパイラ(と、その機能を有効にするための設定)が必要になります。


views::zip を使ったサンプルコード

このコードは、3つの異なるコンテナ(ids, names, prices)を、views::zip を使って同時にループ処理し、各要素を組み合わせて出力します。

完成コード

#include <iostream>
#include <vector>
#include <string>
#include <ranges> // views::zip を使うために必要

using namespace std;

int main() {
    vector<int> ids = {101, 102, 103};
    vector<string> names = {"りんご", "みかん", "ぶどう"};
    vector<int> prices = {120, 80, 250};

    // --- C++23 views::zip を使った方法 ---
    cout << "--- 商品リスト ---" << endl;
    for (const auto& [id, name, price] : views::zip(ids, names, prices)) {
        cout << "ID: " << id << ", 商品名: " << name << ", 価格: " << price << "円" << endl;
    }

    return 0;
}

実行結果

--- 商品リスト ---
ID: 101, 商品名: りんご, 価格: 120円
ID: 102, 商品名: みかん, 価格: 80円
ID: 103, 商品名: ぶどう, 価格: 250円

コードの解説

for (const auto& [id, name, price] : views::zip(ids, names, prices))

これが zip を使ったループ処理の核心部分です。

  • views::zip(...): 引数として渡された複数のコンテナ (ids, names, prices) を圧縮するビューを返します。このビューは、{101, "りんご", 120}, {102, "みかん", 80}, … というように、各コンテナの同じインデックスの要素をまとめたタプルの集まりと考えることができます。
  • [id, name, price]: C++17で導入された「構造化束縛 (structured binding)」です。zip が生成したタプル {101, "りんご", 120} を受け取り、その最初の値を id に、2番目の値を name に、3番目の値を price という名前の変数に、それぞれ自動で分解して代入してくれます。

コンテナの要素数が異なる場合

zip に渡されたコンテナの要素数が異なる場合、ループは最も要素数が少ないコンテナが終わるまでしか実行されません。

vector<int> nums = {1, 2};
vector<string> text = {"A", "B", "C"};

// nums の要素数(2)に合わせて、2回しかループしない
for (const auto& [n, t] : views::zip(nums, text)) {
    cout << n << ": " << t << endl;
}
// 実行結果:
// 1: A
// 2: B

まとめ

今回は、C++23で導入された std::views::zip を使って、複数のコンテナの要素をインデックスを揃えて同時にループ処理する方法を解説しました。

  • std::views::zip(コンテナ1, コンテナ2, ...) で、要素をまとめたビューを作成する。
  • 範囲for文と構造化束縛 [v1, v2, ...] を組み合わせて、各要素を直接受け取る。
  • ループの回数は、最も短いコンテナのサイズに合わせられる。

zip は、Pythonなどの他の言語では標準的に備わっていた便利な機能です。インデックスを使った古いforループを書く必要がなくなり、コードの可読性と安全性を大幅に向上させることができます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次