Namespaces
Variants

std::for_each

Из ru.cppreference.net
 
 
Библиотека алгоритмов
Ограниченные алгоритмы и алгоритмы для диапазонов (C++20)
Ограниченные алгоритмы, например ranges::copy, ranges::sort, ...
Операции с последовательностями без модификации    
Пакетные операции
(C++17)
Операции поиска
Операции модификации последовательностей
Операции копирования
(C++11)
(C++11)
Операции обмена
Операции преобразования
Операции генерации
Операции удаления
Операции изменения порядка
(до C++17)(C++11)
(C++20)(C++20)
Операции выборки
(C++17)

Сортировка и связанные операции
Операции разделения
(C++11)    

Операции сортировки
Операции двоичного поиска
(на разбитых диапазонах)
Операции над множествами (на сортированных диапазонах)
Операции слияния (на сортированных диапазонах)
Операции с кучей
Операции минимума/максимума
(C++11)
(C++17)
Операции лексикографического сравнения
Операции перестановок


Политики выполнения (C++17)
(только для пояснения*)(C++26)

Численные операции
(C++11)
(C++17)
(C++17)    

Специализированные <memory> алгоритмы

Специализированные <random> алгоритмы
Библиотека C









 
Определён в заголовке <algorithm>
template< class InputIt, class UnaryFunc >
UnaryFunc for_each( InputIt first, InputIt last, UnaryFunc f );
(1) (constexpr начиная с C++20)
template< class ExecutionPolicy, class ForwardIt, class UnaryFunc >
void for_each( ExecutionPolicy&& policy,
               ForwardIt first, ForwardIt last, UnaryFunc f );
(2) (начиная с C++17)

Применяет заданный вызываемый объект f к каждому элементу в целевом диапазоне [first, last). Если f возвращает результат, результат игнорируется.

1) f применяется по порядку, начиная с first.

Если UnaryFunc не является MoveConstructible, поведение не определено.

(начиная с C++11)
2) f может не применяться по порядку. Алгоритм выполняется в соответствии с policy.
В отличие от других параллельных алгоритмов, for_each не разрешается делать произвольные копии элементов из целевого диапазона.
Эта перегрузка участвует в разрешении перегрузки только если значение следующего выражения равно true:

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>

(до C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>

(начиная с C++20)
Если UnaryFunc не является CopyConstructible, поведение не определено.

Параметры

first, last - пара итераторов, определяющая целевой диапазон
f - функциональный объект, применяемый к элементам

Сигнатура функции должна быть эквивалентна следующей:

void fun(const Type &a);

Сигнатура не должна иметь const &.
Тип Type должен быть таким, чтобы объект типа InputIt можно разыменовать и затем неявно преобразовать в Type.

​

policy - политика выполнения для использования
Требования к типам
-
InputIt должен соответствовать требованиям LegacyInputIterator.
-
ForwardIt должен соответствовать требованиям LegacyForwardIterator.

Возвращаемое значение

1) 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++17)
применяет функциональный объект к первым N элементам последовательности
(шаблон функции & алгоритмический функциональный объект)
применяет функцию к диапазону элементов, сохраняя результаты в целевом диапазоне
(шаблон функции & алгоритмический функциональный объект)
цикл for по forдиапазону(C++11) выполняет цикл по диапазону