std:: for_each
|
ヘッダーで定義
<algorithm>
|
||
|
template
<
class
InputIt,
class
UnaryFunc
>
UnaryFunc for_each ( InputIt first, InputIt last, UnaryFunc f ) ; |
(1) | (constexpr since C++20) |
|
template
<
class
ExecutionPolicy,
class
ForwardIt,
class
UnaryFunc
>
void
for_each
(
ExecutionPolicy
&&
policy,
|
(2) | (since C++17) |
指定された単項
関数オブジェクト
f
を、
イテレータ
の範囲
レンジ
[
first
,
last
)
内のすべてのイテレータをデリファレンスした結果に適用します。
f
が結果を返す場合、その結果は無視されます。
|
std:: is_execution_policy_v < std:: decay_t < ExecutionPolicy >> が true であること。 |
(C++20まで) |
|
std:: is_execution_policy_v < std:: remove_cvref_t < ExecutionPolicy >> が true であること。 |
(C++20以降) |
イテレータ型(
InputIt
/
ForwardIt
)が変更可能な場合、
f
は間接参照されたイテレータを通じて
範囲
の要素を変更する可能性があります。
他の並列アルゴリズムとは異なり、
for_each
は、たとえ要素が
TriviallyCopyable
であっても、シーケンス内の要素のコピーを作成することが許可されていません。
目次 |
パラメータ
| first, last | - | 関数オブジェクトが適用される要素の 範囲 を定義するイテレータのペア |
| policy | - | 使用する 実行ポリシー |
| f | - |
範囲
範囲
[
first
,
last
)
内のすべてのイテレータを間接参照した結果に適用される関数オブジェクト
関数のシグネチャは以下と同等であるべきです: void fun ( const Type & a ) ;
シグネチャは
const
&
を持つ必要はありません。
|
| 型要件 | ||
-
InputIt
は
LegacyInputIterator
の要件を満たさなければなりません。
|
||
-
ForwardIt
は
LegacyForwardIterator
の要件を満たさなければなりません。
|
||
戻り値
計算量
正確に std:: distance ( first, last ) 回の f の適用。
例外
テンプレートパラメータ
ExecutionPolicy
を持つオーバーロードは、
以下のようにエラーを報告します:
-
アルゴリズムの一部として呼び出された関数の実行が例外をスローした場合、
ExecutionPolicyが 標準ポリシー のいずれかであるとき、 std::terminate が呼び出されます。それ以外のExecutionPolicyについては、動作は実装定義です。 - アルゴリズムがメモリの確保に失敗した場合、 std::bad_alloc がスローされます。
実装例
実装例については 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以降は暗黙的なムーブ } |
注記
オーバーロード ( 1 ) に対して、 f はステートフルな関数オブジェクトを指定できます。戻り値はバッチ操作の最終状態と見なすことができます。
オーバーロード ( 2 ) では、並列呼び出しを実行するために f の複数のコピーが作成される可能性があります。並列化では効率的な状態の蓄積がしばしば不可能であるため、値は返されません。
例
以下の例では、
lambda-expression
を使用してベクトルの全要素をインクリメントし、その後に関数オブジェクト(別名「ファンクタ」)内でオーバーロードされた
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++17)
|
シーケンスの最初のN個の要素に関数オブジェクトを適用する
(関数テンプレート) |
|
(C++20)
|
単項
関数オブジェクト
を
範囲
の要素に適用する
(アルゴリズム関数オブジェクト) |
|
(C++20)
|
シーケンスの最初のN個の要素に関数オブジェクトを適用する
(アルゴリズム関数オブジェクト) |
範囲ベース
for
ループ
(C++11)
|
範囲に対するループを実行する |