Namespaces
Variants

std:: for_each

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
for_each
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
Определено в заголовке <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 .
Эта перегрузка участвует в разрешении перегрузки только при выполнении всех следующих условий:

std:: is_execution_policy_v < std:: decay_t < ExecutionPolicy >> равно true .

(до C++20)

std:: is_execution_policy_v < std:: remove_cvref_t < ExecutionPolicy >> равно true .

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

Если тип итератора ( InputIt / ForwardIt ) является изменяемым, f может модифицировать элементы диапазона через разыменованный итератор.

В отличие от остальных параллельных алгоритмов, for_each не разрешается создавать копии элементов в последовательности, даже если они являются TriviallyCopyable .

Содержание

Параметры

first, last - пара итераторов, определяющих диапазон элементов, к которым будет применён функциональный объект
policy - политика выполнения, которая будет использована
f - функциональный объект, который будет применён к результату разыменования каждого итератора в диапазоне [ first , last )

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

void fun ( const Type & a ) ;

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

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

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

1) f
2) (нет)

Сложность

Ровно std:: distance ( first, last ) применений функции f .

Исключения

Перегрузка с параметром шаблона с именем ExecutionPolicy сообщает об ошибках следующим образом:

  • Если выполнение функции, вызванной как часть алгоритма, выбрасывает исключение и ExecutionPolicy является одним из стандартных политик , std::terminate вызывается. Для любой другой ExecutionPolicy поведение определяется реализацией.
  • Если алгоритму не удается выделить память, std::bad_alloc выбрасывается.

Возможная реализация

Смотрите также реализации в 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; // неявное перемещение начиная с C++11
}

Примечания

Для перегрузки ( 1 ) , f может быть функциональным объектом с состоянием. Возвращаемое значение может рассматриваться как конечное состояние пакетной операции.

Для перегрузки ( 2 ) может быть создано несколько копий f для выполнения параллельного вызова. Значение не возвращается, поскольку параллелизация часто не позволяет эффективно накапливать состояние.

Пример

Следующий пример использует lambda-expression для инкремента всех элементов вектора, а затем использует перегруженный operator() в функциональном объекте (также известном как "functor") для вычисления их суммы. Обратите внимание, что для вычисления суммы рекомендуется использовать специализированный алгоритм 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 Applied to Behavior as published Correct behavior
LWG 475 C++98 было неясно, может ли f изменять элементы
последовательности, по которой выполняется итерация ( for_each классифицируется
как "немодифицирующие операции с последовательностями")
прояснено (разрешено, если тип
итератора является изменяемым)
LWG 2747 C++11 перегрузка ( 1 ) возвращала std :: move ( f ) возвращает f (что неявно выполняет перемещение)

Смотрите также

применяет функцию к диапазону элементов, сохраняя результаты в целевом диапазоне
(шаблон функции)
(C++17)
применяет функциональный объект к первым N элементам последовательности
(шаблон функции)
применяет унарный функциональный объект к элементам из диапазона
(функциональный объект алгоритма)
применяет функциональный объект к первым N элементам последовательности
(функциональный объект алгоритма)
цикл по диапазону for (C++11) выполняет цикл по диапазону