namespace std::ranges {
template <input_iterator I,
sentinel_for<I> S,
class Proj = identity,
indirectly_unary_invocable<projected<I, Proj>> Fun>
constexpr for_each_result<I, Fun>
for_each(I first,
S last,
Fun f,
Proj proj = {}); // (1) C++20
template <input_range R,
class Proj = identity,
indirectly_unary_invocable<projected<iterator_t<R>, Proj>> Fun>
constexpr for_each_result<borrowed_iterator_t<R>, Fun>
for_each(R&& r,
Fun f,
Proj proj = {}); // (2) C++20
template <execution-policy Ep,
random_access_iterator I,
sized_sentinel_for<I> S,
class Proj = identity,
indirectly_unary_invocable<projected<I, Proj>> Fun>
I for_each(Ep&& exec,
I first,
S last,
Fun f,
Proj proj = {}); // (3) C++26
template <execution-policy Ep,
sized-random-access-range R,
class Proj = identity,
indirectly_unary_invocable<projected<iterator_t<R>, Proj>> Fun>
borrowed_iterator_t<R>
for_each(Ep&& exec,
R&& r,
Fun f,
Proj proj = {}); // (4) C++26
}
概要
範囲の全ての要素に、指定された関数を適用する。
- (1): イテレータ範囲を指定する
- (2): Rangeを直接指定する
- (3): (1)の並列アルゴリズム版。実行ポリシーを指定する
- (4): (2)の並列アルゴリズム版。実行ポリシーを指定する
テンプレートパラメータ制約
- (1):
Iがinput_iteratorであるSがIに対する番兵であるFunはIをProjで射影した値を受け取る1引数のinvocableである
- (2):
Rがinput_rangeであるFunはRのイテレータをProjで射影した値を受け取る1引数のinvocableである
この他にFunはcopy_constructibleのモデルであることが要求される。
効果
[first,last) 内の全てのイテレータ i に invoke(f, invoke(proj, *i)) という操作を行う。first から順番に処理し、last - 1 まで行う。
このアルゴリズムはその他のアルゴリズムと違い、invoke(proj, *i) が書き換え可能な参照であれば、関数 f の内部でその値を書き換えても構わない。
戻り値
-
(1), (2):
for_each_result { .in = last, .fun = std::move(f), } -
(3), (4):
last
計算量
正確に f を last - first 回適用する
備考
fに戻り値がある場合、それは単に無視される
例
基本的な使い方
#include <iostream>
#include <array>
#include <algorithm>
int main() {
std::array v = { 3, 1, 4 };
// vの全ての要素にラムダ式を適用する
std::ranges::for_each(v, [](int x) { std::cout << x << std::endl; });
std::cout << "----" << std::endl;
// 要素の内容を書き換えても構わないし、呼び出し順序に依存した処理を書いても構わない
int n = 0;
std::ranges::for_each(v, [n](int& x) mutable { x += n++; });
std::ranges::for_each(v, [](int x) { std::cout << x << std::endl; });
}
出力
3
1
4
----
3
2
6
並列アルゴリズムの例 (C++26)
#include <iostream>
#include <vector>
#include <algorithm>
#include <execution>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
// 並列に全ての要素を2倍にする
std::ranges::for_each(std::execution::par, v, [](int& x) { x *= 2; });
for (int x : v) {
std::cout << x << ' ';
}
std::cout << std::endl;
}
出力
2 4 6 8 10
バージョン
言語
- C++20
処理系
- Clang: ??
- GCC: 10.1.0 ✅
- ICC: ??
- Visual C++: 2019 Update 10 ✅
実装例
struct for_each_impl {
template<input_iterator I, sentinel_for<I> S, class Proj = identity, indirectly_unary_invocable<projected<I, Proj>> Fun>
requires copy_constructible<Fun>
constexpr for_each_result<I, Fun> operator()(I first, S last, Fun f, Proj proj = {}) const {
for (; first != last; ++first) {
invoke(f, invoke(proj, *first));
}
return {move(first), move(f)};
}
template<input_range R, class Proj = identity, indirectly_unary_invocable<projected<iterator_t<R>, Proj>> Fun>
requires copy_constructible<Fun>
constexpr for_each_result<borrowed_iterator_t<R>, Fun> operator()(R&& r, Fun f, Proj proj = {}) const {
return (*this)(begin(r), end(r), move(f), ref(proj));
}
};
inline constexpr for_each_impl for_each;