名前空間
変種
操作

std::for_each

From cppreference.com
< cpp‎ | algorithm
 
 
アルゴリズムライブラリ
制約付きアルゴリズムとRangeアルゴリズム (C++20)
制約付きアルゴリズム、例: ranges::copy, ranges::sort, ...
実行ポリシー (C++17)
シーケンスを変更しない操作
一括操作
for_each
(C++17)
検索操作
(C++11)                (C++11)(C++11)

シーケンスを変更する操作
コピー操作
(C++11)
(C++11)
スワップ操作
変換操作
生成操作
削除操作
順序変更操作
(C++17まで)(C++11)
(C++20)(C++20)
サンプリング操作
(C++17)

ソートおよび関連操作
パーティション操作
ソート操作
二分探索操作
(パーティション化された範囲)
集合操作 (ソート済み範囲)
マージ操作 (ソート済み範囲)
ヒープ操作
最小/最大操作
(C++11)
(C++17)
辞書順比較操作
順列操作
Cライブラリ
数値演算
未初期化メモリに対する操作
 
ヘッダー <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 を、[firstlast)範囲内のすべてのイテレータのデリファレンス結果に適用します。f が結果を返した場合、その結果は無視されます。

1) ffirst から順に適用されます。

UnaryFuncMoveConstructible でない場合、動作は未定義です。

(C++11以降)
2) f は順序通りに適用されない場合があります。アルゴリズムは policy に従って実行されます。
このオーバーロードは、以下のすべての条件が満たされた場合にのみオーバーロード解決に参加します。

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以降)
UnaryFuncCopyConstructible でない場合、動作は未定義です。

イテレータ型 (InputIt/ForwardIt) がミュータブルな場合、f はデリファレンスされたイテレータを通して範囲の要素を変更する可能性があります。

他の並列アルゴリズムとは異なり、for_each はシーケンスの要素がTriviallyCopyableであっても、コピーを作成することは許されません。

目次

[編集] パラメータ

first, last - 関数オブジェクトが適用される要素の範囲を定義するイテレータの組
policy - 使用する 実行ポリシー
f - 関数オブジェクト。[firstlast)範囲内のすべてのイテレータのデリファレンス結果に適用されます。

関数のシグネチャは以下と同等である必要があります。

 void fun(const Type &a);

シグネチャは const & を持つ必要はありません。
 Type は、InputIt 型のオブジェクトがデリファレンスされ、暗黙的に  Type に変換できるような型でなければなりません。

型要件
-
InputItLegacyInputIterator の要件を満たす必要があります。
-
ForwardItLegacyForwardIterator の要件を満たさなければなりません。

[編集] 戻り値

1) f
2) (なし)

[編集] 計算量

正確に 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; // implicit move since C++11
}

[編集] 備考

オーバーロード (1) の場合、f はステートフルな関数オブジェクトにすることができます。戻り値は、バッチ操作の最終状態と見なすことができます。

オーバーロード (2) の場合、並列呼び出しを実行するために f の複数のコピーが作成されることがあります。並列化では効率的な状態の蓄積が困難なことが多いため、値は返されません。

[編集]

以下の例では、ラムダ式を使用してベクトルのすべての要素をインクリメントし、次に関数オブジェクト(「ファンクタ」)のオーバーロードされた 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 は「非変更シーケンス操作」に分類されるため)
イテレート中のシーケンスの要素を変更できるか不明確だった(for_each
「非変更シーケンス操作」に分類されるため)
明確化された(イテレータ型がミュータブルな場合は許可される)
イテレータ型がミュータブルな場合は許可される
LWG 2747 C++11 オーバーロード (1)std::move(f) を返していた f を返す(暗黙的にムーブされる)

[編集] 関連項目

範囲内の要素に関数を適用し、結果を結果範囲に格納する
(関数テンプレート) [編集]
シーケンスの最初のN個の要素に関数オブジェクトを適用する
(関数テンプレート) [編集]
範囲内の要素に単項関数オブジェクトを適用する
(アルゴリズム関数オブジェクト)[編集]
シーケンスの最初のN個の要素に関数オブジェクトを適用する
(アルゴリズム関数オブジェクト)[編集]
範囲forループ(C++11) 範囲に対するループを実行する[編集]
English 日本語 中文(简体) 中文(繁體)