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
}
概要
範囲の全ての要素に、指定された関数を適用する。
- (1): イテレータ範囲を指定する
- (2): Rangeを直接指定する
テンプレートパラメータ制約
- (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
の内部でその値を書き換えても構わない。
戻り値
for_each_result {
.in = last,
.fun = std::move(f),
}
計算量
正確に f
を last - first
回適用する
備考
f
に戻り値がある場合、それは単に無視される
例
#include <iostream>
#include <array>
#include <algorithm>
int main() {
constexpr 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
処理系
- 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;