最終更新日時: 2026年04月13日 15時17分49秒 (JST)
teruyamato0731 が更新

履歴 編集

function template
<algorithm>

# std::for_each

    namespace std {
      template <class InputIterator, class Function>
      Function for_each(InputIterator first,
                        InputIterator last,
                        Function f);                   // (1) C++03

      template <class InputIterator, class Function>
      constexpr Function for_each(InputIterator first,
                                  InputIterator last,
                                  Function f);         // (1) C++20

      template <class ExecutionPolicy, class ForwardIterator, class Function>
      void for_each(ExecutionPolicy&& exec,
                    ForwardIterator first,
                    ForwardIterator last,
                    Function f);                       // (2) C++17
    }

## 概要

イテレータ範囲`[first, last)`の全ての要素に、指定された関数を適用する。

## 要件

`Function` は `MoveConstructible` の要件を満たす必要があるが、`CopyConstructible` の要件を満たす必要はない。（C++11のみ）

## 効果

`[first,last)` 内の全てのイテレータ `i` に `f(*i)` という操作を行う。`first` から順番に処理し、`last - 1` まで行う。

このアルゴリズムはその他のアルゴリズムと違い、関数 `f` の内部で `*i` の値を書き換えても構わない（もちろんイテレータの型が `mutable iterator` の要件を満たしている場合に限る）。

## 戻り値

- C++03 の場合 : `f`
- C++11 の場合 : `std::move(f)`

## 計算量

正確に `f` を `last - first` 回適用する

## 備考

- `f` に戻り値がある場合、それは単に無視される
- (1)は、戻り値の型が`Function`となっている。シングルスレッドでの順次実行では関数オブジェクト`f`の状態を次々に変更していき、最終的な関数オブジェクトの状態を戻り値として取得できる
- (2)の並列アルゴリズム版は、戻り値の型が`Function`ではなく`void`となっている。並列数だけ関数オブジェクトをコピーするため、関数オブジェクトの状態を順次変更していくような設計は、並列アルゴリズム版ではできないようになっている

## 例

### C++03での例

    #include <iostream>
    #include <vector>
    #include <algorithm>

    void disp(int x) {
      std::cout << x << std::endl;
    }

    struct mutate {
      int n;
      mutate() : n(0) { }
      void operator()(int& v) {
        v += n++;
      }
    };

    int main() {
      std::vector<int> v;

      v.push_back(3);
      v.push_back(1);
      v.push_back(4);

      // vの全ての要素にdisp()関数を適用する
      std::for_each(v.begin(), v.end(), disp);

      std::cout << "----" << std::endl;

      // 要素の内容を書き換えても構わないし、呼び出し順序に依存した処理を書いても構わない
      std::for_each(v.begin(), v.end(), mutate());
      std::for_each(v.begin(), v.end(), disp);
    }

#### 出力

    3
    1
    4
    ----
    3
    2
    6

## 例

### C++11での例

    #include <iostream>
    #include <vector>
    #include <algorithm>

    int main() {
      std::vector<int> v = { 3, 1, 4 };

      // vの全ての要素にラムダ式を適用する
      std::for_each(v.begin(), v.end(), [](int x) { std::cout << x << std::endl; });

      std::cout << "----" << std::endl;

      // 要素の内容を書き換えても構わないし、呼び出し順序に依存した処理を書いても構わない
      int n = 0;
      std::for_each(v.begin(), v.end(), [n](int& x) mutable { x += n++; });
      std::for_each(v.begin(), v.end(), [](int x) { std::cout << x << std::endl; });
    }

#### 出力

    3
    1
    4
    ----
    3
    2
    6

### 処理系

- Clang:
- GCC:
- ICC:
- Visual C++: 2005 ✅, 2008 ✅, 2010 ✅, 2012 ✅, 2013 ✅, 2015 ✅
  - C++11への対応（戻り値のムーブ）は2012から。

## 実装例

    template <class InputIterator, class Function>
    Function for_each(InputIterator first, InputIterator last, Function f) {
      for ( ; first != last; ++first)
        f(*first);
      return move(f);
    }

## 関連項目

- `ranges::for_each`

## 参照

- P0202R3 Add Constexpr Modifiers to Functions in `<algorithm>` and `<utility>` Headers
- P0467R2 Iterator Concerns for Parallel Algorithms