std::for_each
Определён в заголовочном файле <algorithm> | ||
|---|---|---|
template< class InputIt, class UnaryFunc > UnaryFunc for_each( InputIt first, InputIt last, UnaryFunc f ); | (1) | (constexpr since C++20) |
template< class ExecutionPolicy, class ForwardIt, class UnaryFunc >
void for_each( ExecutionPolicy&& policy,
ForwardIt first, ForwardIt last, UnaryFunc f );
| (2) | (since C++17) |
Применяет заданный вызываемый объект f к каждому элементу целевого диапазона [first, last). Если f возвращает результат, этот результат игнорируется.
f применяется по порядку, начиная с first. | Если | (since C++11) |
f может применяться не по порядку. Алгоритм выполняется согласно policy.for_each не может создавать произвольные копии элементов целевого диапазона.true: |
| (until C++20) |
|
| (since C++20) |
UnaryFunc не является CopyConstructible, поведение не определено.Параметры
| first, last | - | пара итераторов, задающих целевой диапазон |
| f | - | функциональный объект, применяемый к элементам Сигнатура функции должна быть эквивалентна следующей: voidfun(constType&a); Сигнатура не обязана содержать |
| policy | - | используемая политика выполнения |
| Требования к типам | ||
-InputIt должен соответствовать требованиям LegacyInputIterator. |
||
-ForwardIt должен соответствовать требованиям LegacyForwardIterator. |
||
Возвращаемое значение
f
Сложность
Ровно std::distance(first, last) вызовов f.
Исключения
2) В процессе выполнения:- Если временные ресурсы памяти, необходимые для распараллеливания, недоступны, выбрасывается
std::bad_alloc. - Если при обращении к объектам через аргумент алгоритма выбрасывается неперехваченное исключение, поведение определяется политикой выполнения (для стандартных политик вызывается
std::terminate).
Примечания
Если тип итератора (InputIt/ForwardIt) является изменяемым, f может изменять элементы целевого диапазона.
Для перегрузки (1) f может быть функциональным объектом с состоянием. Возвращаемое значение можно рассматривать как конечное состояние пакетной операции.
Для перегрузки (2) для параллельного вызова может создаваться несколько копий f. Значение не возвращается, поскольку распараллеливание часто не позволяет эффективно накапливать состояние.
Возможная реализация
См. также реализации в 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
}
|
Пример
В следующем примере используется лямбда-выражение, чтобы увеличить все элементы вектора, а затем перегруженный 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классифицируется как «немодифицирующая операция над последовательностью») | уточнено (разрешено, если тип итератора является изменяемым) |
| LWG 2747 | C++11 | перегрузка (1) возвращала std::move(f) | возвращает f (что выполняет неявное перемещение) |
См. также
|
(C++20) | применяет унарный функциональный объект к элементам из диапазона (функциональный объект алгоритма) |
|
(C++17) | применяет функциональный объект к первым N элементам последовательности (шаблон функции и функциональный объект алгоритма) |
|
(C++20) | |
| применяет функцию к диапазону элементов, сохраняя результаты в целевом диапазоне (шаблон функции и функциональный объект алгоритма) |
|
|
(C++20) | |
цикл range-for(C++11) | выполняет цикл по диапазону |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/algorithm/for_each