ホームに戻る
出典 :
関連 :
目次 :
範囲ベース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 も使用できる。