std::for_each
(on partitioned ranges)
<algorithm>
void for_each( ExecutionPolicy&& policy,
Applies the given unary function object f to the result of dereferencing every iterator in the range [
first,
last)
. If f returns a result, the result is ignored.
If UnaryFunc
is not MoveConstructible, the behavior is undefined.
std::is_execution_policy_v <std::decay_t <ExecutionPolicy>> is true.
(until C++20)std::is_execution_policy_v <std::remove_cvref_t <ExecutionPolicy>> is true.
(since C++20)If the iterator type (InputIt
/ForwardIt
) is mutable, f may modify the elements of the range through the dereferenced iterator.
Unlike the rest of the parallel algorithms, for_each
is not allowed to make copies of the elements in the sequence even if they are TriviallyCopyable.
[
first,
last)
The signature of the function should be equivalent to the following:
void fun(const Type &a);
The signature does not need to have const &.
The type Type must be such that an object of type InputIt can be dereferenced and then implicitly converted to Type.
InputIt
must meet the requirements of LegacyInputIterator.
ForwardIt
must meet the requirements of LegacyForwardIterator.
Exactly std::distance (first, last) applications of f.
The overload with a template parameter named ExecutionPolicy
reports errors as follows:
ExecutionPolicy
is one of the standard policies, std::terminate is called. For any other ExecutionPolicy
, the behavior is implementation-defined.
See also the implementations in libstdc++, libc++ and 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 }
For overload (1), f can be a stateful function object. The return value can be considered as the final state of the batch operation.
For overload (2), multiple copies of f may be created to perform parallel invocation. No value is returned because parallelization often does not permit efficient state accumulation.
The following example uses a lambda-expression to increment all of the elements of a vector and then uses an overloaded operator()
in a function object (i.k.a., "functor") to compute their sum. Note that to compute the sum, it is recommended to use the dedicated algorithm 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'; }
Output:
before: 3 -4 2 -8 15 267 after: 4 -3 3 -7 16 268 sum: 281
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
LWG 475 | C++98 | it was unclear whether f can modify the elements of the sequence being iterated over ( for_each isclassified as "non-modifying sequence operations") |
made clear (allowed if the iterator type is mutable) |
LWG 2747 | C++11 | overload (1) returned std::move(f) | returns f (which implicitly moves) |