std::for_each
| ヘッダで定義 <algorithm>
|
||
template< class InputIt, class UnaryFunc >
UnaryFunc for_each( InputIt first, InputIt last, UnaryFunc f );
|
(1) | (C++20 から constexpr) |
template< class ExecutionPolicy, class ForwardIt, class UnaryFunc >
void for_each( ExecutionPolicy&& policy,
ForwardIt first, ForwardIt last, UnaryFunc f );
|
(2) | (C++17 から) |
指定された呼び出し可能オブジェクト f を、対象範囲 [first, last) の各要素に適用します。f が結果を返す場合、その結果は無視されます。
f は順に適用されない可能性があります。アルゴリズムは policy に従って実行されます。for_each は対象範囲の要素の任意のコピーを作成することが許可されていません。true である場合にのみオーバーロード解決に参加します。
|
|
(C++20 まで) |
|
|
(C++20 から) |
UnaryFunc が CopyConstructible でない場合、動作は未定義です。パラメータ
| first, last | - | ターゲット範囲を定義するイテレータのペア範囲 |
| f | - | 要素に適用される関数オブジェクト 関数のシグネチャは以下と同等でなければなりません:
シグネチャに |
| ポリシー | - | 使用する 実行ポリシー |
| 型要件 | ||
-InputItはLegacyInputIteratorの要件を満たさなければならない。
| ||
-ForwardItはLegacyForwardIteratorの要件を満たさなければならない。
| ||
戻り値
f計算量
正確に std:: distance ( first, last ) 回の f の適用。
例外
- 並列化に必要な一時メモリリソースが利用できない場合、std::bad_allocが送出されます。
- アルゴリズムの引数を介してオブジェクトにアクセス中にキャッチされない例外が送出された場合、動作は実行ポリシーによって決まります(標準ポリシーの場合、std::terminateが呼び出されます)。
ノート
イテレータの型 (InputIt/ForwardIt) が変更可能であれば、f はターゲット範囲内の要素を変更することができます。
オーバーロード (1) の場合、f は状態を持つ呼び出し可能オブジェクトにできます。戻り値はバッチ操作の最終状態とみなすことができます。
オーバーロード (2) の場合、並列呼び出しを実行するために f の複数のコピーが作成されることがあります。並列化では効率的な状態の蓄積が許可されないことが多いため、値は返されません。
実装例
実装例については libstdc++ 、 libc++ および MSVC stdlib も参照してください。
template<class InputIt, class UnaryFunc> constexpr UnaryFunc for_each(InputIt first, InputIt last, UnaryFunc f) { for (; first != last; ++first) f(*first); return f; // C++11以降は暗黙的なムーブ } |
例
次の例では、ラムダ式を使用してベクタのすべての要素をインクリメントし、次にオーバーロードされたoperator()を呼び出し可能オブジェクト内で使用してそれらの和を計算します。なお、和を計算するには、専用アルゴリズムのstd::accumulateを使用することをお勧めします。
#include <algorithm>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v{3, -4, 2, -8, 15, 267};
auto print = [](const int& n) { std::cout << n << ' '; };
std::cout << "before:\t";
std::for_each(v.cbegin(), v.cend(), print);
std::cout << '\n';
// increment elements in-place
std::for_each(v.begin(), v.end(), [](int &n) { n++; });
std::cout << "after:\t";
std::for_each(v.cbegin(), v.cend(), print);
std::cout << '\n';
struct Sum
{
void operator()(int n) { sum += n; }
int sum {0};
};
// invoke Sum::operator() for each element
Sum s = std::for_each(v.cbegin(), v.cend(), Sum());
std::cout << "sum:\t" << s.sum << '\n';
}
出力:
before: 3 -4 2 -8 15 267
after: 4 -3 3 -7 16 268
sum: 281
不具合報告
以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。
| DR | 適用対象 | 公開時の動作 | 正しい動作 |
|---|---|---|---|
| LWG 475 | C++98 |
反復処理中のシーケンス要素を
f
が変更できるか
不明確であった(
for_each
は「非変更シーケンス操作」
に分類されていた) |
明確化(イテレータ型がmutableの
場合に許可) |
| LWG 2747 | C++11 | オーバーロード ( 1 ) が std :: move ( f ) を返していた | f を返す(暗黙的にmoveが行われる) |
関連項目
(C++20) |
単項を適用する関数オブジェクトをあるからの要素に範囲 (アルゴリズム関数オブジェクト) |
(C++17) |
シーケンスの最初のN個の要素に関数オブジェクトを適用する (関数テンプレート & アルゴリズム関数オブジェクト) |
(C++20) |
|
| 要素の範囲に関数を適用し、結果を出力範囲に格納する (関数テンプレート & アルゴリズム関数オブジェクト) | |
(C++20) |
|
範囲-for ループ(C++11)
|
範囲に対してループを実行する |