Daily bit(e) C++. std::for_each
Daily bit(e) C++ 60, алгоритм, который применяет вызываемый объект к каждому элементу диапазона в порядке следования: std::for_each.

Алгоритм std::for_each вызывает предоставленный объект для каждого элемента диапазона в порядке следования (слева направо), игнорируя результат. Вызываемый объект может быть с сохранением состояния, и данный алгоритм вернет его в конечном состоянии (после применения ко всем элементам).
Хотя цикл for на основе диапазонов в основном заменил варианты использования std::for_each, он по-прежнему полезен как инструмент тривиального распараллеливания благодаря параллельной версии из C++17. Он также может предложить более читабельное решение при использовании версии для диапазонов с проекцией из C++20.
Обратите внимание, что параллельная версия не работает строго слева направо и не возвращает вызываемый объект.
#include <algorithm>
#include <execution>
#include <vector>
#include <optional>
std::vector<int> data{1, 2, 3, 4, 5};
// Вызываемый объект может изменять элементы
std::for_each(data.begin(), data.end(), [](int& v) { ++v; });
// data == {2, 3, 4, 5, 6}
struct Stateful
{
int sum;
void operator()(int& v)
{
sum += v;
++v;
}
};
auto result = std::for_each(data.begin(), data.end(), Stateful{0});
// data == {3, 4, 5, 6, 7}
// result.sum == 20
struct Custom {};
auto process = [](Custom&){};
std::vector<Custom> rng(10,Custom{});
// Параллельное выполнение из C++17
std::for_each(std::execution::par_unseq, // параллельно, в любом порядке
rng.begin(), rng.end(), // все элементы
process // вызвать process для каждого элемента
);
std::vector<std::optional<int>> opt{{},2,{},4,{}};
// Версия для диапазонов с проекцией из C++20
std::ranges::for_each(opt,
[](int v) {
// пройти по проецируемым значениям
// {0, 2, 0, 4, 0}
},
[](std::optional<int>& v){
// проекция, которая вернет
// содержащееся значение или ноль
return v.value_or(0);
});
