はじめに
プログラミングでは、「商品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
ループを書く必要がなくなり、コードの可読性と安全性を大幅に向上させることができます。