ホームに戻る
出典 :
C++11, C++14, C++17 新機能まとめ ~使いそうなものだけ - Qiita C++11 範囲ベース for ループ 入門
関連 :
C++11 コンテナ イテレータ 型推論 [C#]foreach(範囲ベースfor)
目次 :

範囲ベースforとは

コンテナ(配列などの、複数個のデータを格納する集合)の最初から最後までを走査できる機能。C++11で追加された。
C#やJavaの foreach 文と同様の機能で、C++では for 文の別構文を用いる。

基本的な例

// 配列 ar を宣言、初期化 int ar[] = {1, 2, 3, 4}; : // ar を走査、各要素を出力 for ( int x : ar ) { std::cout << x << "/n"; }
実行結果
1 2 3 4
上記の例では、インデクス(添字)を用いることなく、集合の先頭から末尾までを参照している。
通常の for 文と比較すると、 で、コードが簡潔となる。

コンテナ(STL)に対する適用例

ベクトル( std::vector )

// ベクトル v を宣言、初期化 std::vector<int> v{1, 2, 3, 4}; : // v を走査、各要素を出力 // (添字アクセス) for ( int i = 0; i < (int)v.size(); ++i ) { std::cout << v[i] << "/n"; } std::cout << "/n"; // (イテレータ) for ( auto itr = v.begin(); itr != v.end(); ++itr ) { std::cout << *itr << "/n"; } std::cout << "/n"; // (範囲ベースfor) for ( auto x : v ) { std::cout << x << "/n"; }
実行結果
1 2 3 4 1 2 3 4 1 2 3 4
上記の例では、添字、イテレータ、範囲ベースforのそれぞれでベクトルの走査を行っている。
範囲ベースforは他のいずれよりもコードが簡潔で、コレクションの全体を走査するという意図が伝わりやすい。
(イテレータは end() が末尾要素の次を指すなど慣れを要する。)

また、上記の例にもあるように、要素を格納する一時変数には auto を使用できる。
これはコレクションに格納される要素の型が不明、または変化する場合に有効である。

マップ( std::map )

// マップ mp を宣言 std::map<std::string, int> mp; : // (mp にキーと値のペアを追加) : // mp を走査、各要素のキー(x.first)、値(x.second)を出力 for ( auto x : mp ) { std::cout << x.first << " " << x.second << "/n"; }
マップ(連想配列)の要素はキーと値の組( std::pair )で、first でキーを、second で値を取得できる。
他はベクトルの場合と同様。

要素の書き換え

一時変数に & を付与して宣言すると参照変数となり、集合の要素を書き換えることが可能となる
また、特に要素が構造を持ったデータの場合は参照変数とすることでパフォーマンスを向上できる。
// 配列 ar を宣言、初期化 int ar[] = {1, 2, 3, 4, 1, 6, 1, 9}; : // ar を走査 // (x は参照変数) for ( int& x : ar ) { // x の値が 1 であれば 123 に書き換える if ( x == 1 ) { x = 123; } } // ar は { 1, 2, 3, 4, 1, 6, 1, 9} から // {123, 2, 3, 4, 123, 6, 123, 9} に変化している

はしがき

通常の for ループと同様、break 、continue も使用できる。