目次
はじめに
C++で、「vector
に格納された全ての数値に10を足したい」「全ての文字列を画面に表示したい」といったように、コンテナの全要素に対して、同じ操作を一律に適用したい場面は非常に多くあります。
この記事では、この目的を達成するための2つの主要な方法を解説します。
- 範囲
for
文 (range-based for loop): C++11で導入された、最もシンプルで推奨される方法。 std::for_each
:<algorithm>
ヘッダーで提供される、伝統的なアルゴリズム関数。
1. 範囲for
文 (C++11以降、推奨)
範囲for
文は、コンテナの全要素をループ処理するための、最も簡潔で読みやすい構文です。
サンプルコード
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main() {
vector<string> items = {"りんご", "みかん", "ぶどう"};
// 範囲for文で、各要素の末尾に「さん」を付ける
for (string& item : items) {
item += "さん";
}
// 結果の表示
for (const string& item : items) {
cout << item << endl;
}
return 0;
}
解説:
for (string& item : items)
:items
コンテナの各要素が、ループごとにitem
という変数に参照として渡されます。string&
のように&
を付けて参照にすることで、ループ内でitem
を変更すると、元のコンテナitems
の要素が直接書き換えられます。
2. std::for_each
アルゴリズム
for_each
は、指定された範囲の各要素に対して、引数で渡された関数(またはラムダ式)を一度ずつ適用します。
サンプルコード
#include <iostream>
#include <vector>
#include <algorithm> // for_each
using namespace std;
int main() {
vector<int> numbers = {10, 20, 30};
// for_eachとラムダ式を使って、各要素を2倍にする
for_each(numbers.begin(), numbers.end(), [](int& n){
n *= 2;
});
// 結果の表示
for (int n : numbers) {
cout << n << " ";
}
cout << endl;
return 0;
}
解説
for_each(範囲の開始, 範囲の終了, 適用する処理);
- 第1, 2引数: 処理を適用したい要素の範囲をイテレータで指定します。
- 第3引数: 各要素に適用する処理を、関数やラムダ式で渡します。
[](int& n){ n *= 2; }
: このラムダ式は、「int
型の参照n
を受け取り、その値を2倍にする」という処理を定義しています。引数をint&
のように参照にすることで、元のnumbers
コンテナの要素を直接変更できます。
どちらを使うべきか?
- 可読性とシンプルさ: 範囲
for
文の方が、構文がより直感的で読みやすいため、ほとんどの場合で推奨されます。 - 既存の関数を使いたい場合: 処理内容が既に別の関数として定義されている場合、
for_each
の第3引数にその関数名を渡すことで、簡潔に記述できることがあります。 - 並列処理: C++17以降では、
for_each
に実行ポリシー(例:std::execution::par
)を渡すことで、処理を並列化できる場合があります。
結論として、単純なループ処理では、まず範囲for
文を検討するのがベストプラクティスです。
まとめ
今回は、C++でコンテナの全要素に同じ処理を適用するための、範囲for
文とstd::for_each
を解説しました。
- 範囲
for
文: C++11以降の標準的な方法。簡潔で読みやすい。 std::for_each
: 伝統的なアルゴリズム。特定の場面で有効。
どちらの方法も、コンテナの要素を一つずつ効率的に処理するための強力なツールです。