はじめに
プログラミングでは、「1から10までの数」や「0から始まる10個の数」といった、連続した数値のシーケンスを使ってループ処理を行いたい場面が頻繁にあります。従来は、for (int i = 1; i <= 10; i++)
のように、for
ループの初期化式・条件式・更新式を記述するのが一般的でした。
C++20で導入されたRangesライブラリの std::views::iota
を使えば、このような数値シーケンスを、より宣言的で直感的に生成することができます。
この記事では、iota
ビューの2つの主要な使い方(有限シーケンスと無限シーケンス)について解説します。
【前提】C++20とは?
C++20(シーピープラスにーぜろ)は、2020年に正式化されたC++言語のメジャーアップデート版です。RangesライブラリはこのC++20で導入された主要機能のため、利用するにはC++20に対応したコンパイラが必要です。
views::iota
を使ったサンプルコード
このコードは、iota
を使って「開始値と終了値が指定された有限の数列」と、「開始値のみが指定された無限の数列(をtake
で打ち切ったもの)」をそれぞれ生成し、出力します。
完成コード
#include <iostream>
#include <ranges> // views::iota, views::take を使うために必要
namespace views = std::ranges::views;
int main() {
// 1. 有限シーケンス: 開始値(5)と終了値(10)を指定
// 5から9までの数列を生成 (終了値は含まない)
std::cout << "5から9までの数列: ";
for (int i : views::iota(5, 10)) {
std::cout << i << " ";
}
std::cout << std::endl;
// 2. 無限シーケンス: 開始値(100)のみを指定
// 100から始まる無限の数列を生成し、take(5)で先頭5つを抜き出す
std::cout << "100から始まる数列の先頭5つ: ";
for (int i : views::iota(100) | views::take(5)) {
std::cout << i << " ";
}
std::cout << std::endl;
return 0;
}
実行結果
5から9までの数列: 5 6 7 8 9
100から始まる数列の先頭5つ: 100 101 102 103 104
コードの解説
1. 有限シーケンス: views::iota(開始値, 終了値)
views::iota(5, 10)
のように、引数を2つ渡すと、開始値
から始まり、終了値
の手前までの数値シーケンスを生成します。Pythonの range(5, 10)
と同じような動作です。
この方法は、従来の for
ループ for (int i = 5; i < 10; i++)
を、より意味的に分かりやすく書き換えたものと考えることができます。
2. 無限シーケンス: views::iota(開始値)
views::iota(100)
のように、引数を1つだけ渡すと、開始値
から始まる無限の昇順シーケンス(100, 101, 102, …)を生成します。
このまま for
ループで使うと無限ループになってしまうため、| views::take(5)
のような他のレンジアダプタと組み合わせて、必要な分だけを抜き出して使うのが一般的です。
まとめ
今回は、C++20の std::views::iota
を使って、連続した数値のシーケンスを生成する方法を解説しました。
views::iota(開始, 終了)
: 有限の半開区間[開始, 終了)
の数列を生成する。views::iota(開始)
: 無限の数列を生成する。take
などと組み合わせて使う。
iota
は、単純なインデックスベースのループを、より宣言的で読みやすい範囲for
文で記述できるようにする、Rangesライブラリの便利なツールの一つです。