Namespaces
Variants

std::ranges::for_each, std::ranges::for_each_result

De es.cppreference.net
 
 
Biblioteca de algoritmos
Algoritmos restringidos y algoritmos sobre rangos (C++20)
Algoritmos restringidos, p.ej. ranges::copy, ranges::sort, ...
Operaciones de secuencia no modificadoras    
Operaciones por lotes
(C++17)
Operaciones de búsqueda
Operaciones de secuencia modificadoras
Operaciones de copia
(C++11)
(C++11)
Operaciones de intercambio
Operaciones de transformación
Operaciones de generación
Operaciones de eliminación
Operaciones de cambio de orden
(hasta C++17)(C++11)
(C++20)(C++20)
Operaciones de muestreo
(C++17)

Ordenamiento y operaciones relacionadas
Operaciones de partición
(C++11)    

Operaciones de ordenamiento
Operaciones de búsqueda binaria
(en rangos particionados)
Operaciones de conjuntos (en rangos ordenados)
Operaciones de mezcla (en rangos ordenados)
Operaciones de montículo (heap)
Operaciones de mínimo/máximo
(C++11)
(C++17)
Operaciones de comparación lexicográfica
Operaciones de permutación


 
Algoritmos restringidos
Todos los nombres en este menú pertenecen al espacio de nombres std::ranges
Operaciones de secuencia no modificadoras
Operaciones de secuencia modificadoras
Operaciones de partición
Operaciones de ordenamiento
Operaciones de búsqueda binaria (en rangos ordenados)
       
       
Operaciones de conjuntos (en rangos ordenados)
Operaciones de montículo (heap)
Operaciones de mínimo/máximo
       
       
Operaciones de permutación
Operaciones de plegado
Operaciones sobre almacenamiento no inicializado
Tipos de retorno
 
Definido en el encabezado <algorithm>
Firma de llamada
template< std::input_iterator I, std::sentinel_for<I> S,
          class Proj = std::identity,
          std::indirectly_unary_invocable<std::projected<I, Proj>> Fun >
constexpr for_each_result<I, Fun>
    for_each( I first, S last, Fun f, Proj proj = {} );
(1) (desde C++20)
template< ranges::input_range R, class Proj = std::identity,
          std::indirectly_unary_invocable
              <std::projected<ranges::iterator_t<R>, Proj>> Fun >
constexpr for_each_result<ranges::borrowed_iterator_t<R>, Fun>
    for_each( R&& r, Fun f, Proj proj = {} );
(2) (desde C++20)
template< /*execution-policy*/ Ep, std::random_access_iterator I,
          std::sized_sentinel_for<I> S, class Proj = std::identity,
          std::indirectly_unary_invocable<std::projected<I, Proj>> Fun >
I for_each( Ep&& policy, I first, S last, Fun f, Proj proj = {} );
(3) (desde C++26)
template< /*execution-policy*/ Ep,
          /*sized-random-access-range*/ R, class Proj = std::identity,
          std::indirectly_unary_invocable
              <std::projected<ranges::iterator_t<R>, Proj>> Fun >
ranges::borrowed_iterator_t<R>
    for_each( Ep&& policy, R&& r, Fun f, Proj proj = {} );
(4) (desde C++26)
Tipos auxiliares
template< class I, class F >
using for_each_result = ranges::in_fun_result<I, F>;
(5) (desde C++20)

Para la definición de /*execution-policy*/, véase esta página; para la definición de /*sized-random-access-range*/, véase esta página.

Aplica el objeto invocable dado f a cada elemento (proyectado por proj) en el rango objetivo [firstlast) o r. Si f devuelve un resultado, se ignora.

1,2) f se aplica en orden desde el inicio del rango objetivo.
3,4) f podría no aplicarse en orden. El algoritmo se ejecuta de acuerdo con policy.
A diferencia de otros algoritmos paralelos, for_each no puede hacer copias arbitrarias de elementos del rango objetivo.

Las entidades similares a funciones descritas en esta página son objetos de función de algoritmo (conocidos informalmente como niebloids), es decir:

Parámetros

first, last - el par de iteradores que definen el rango
r - el rango objetivo
f - el objeto invocable que se aplicará a los elementos (proyectados)
proj - la proyección que se aplicará a los elementos
policy - la política de ejecución que se usará

Valor de retorno

1) {last, std::move(f)}
2) {ranges::next(ranges::begin(r), ranges::end(r)), std::move(f)} si R modela forward_range, de lo contrario (desde C++26){ranges::end(r), std::move(f)}
3) last
4) ranges::next(ranges::begin(r), ranges::end(r)) si R modela forward_range, de lo contrario (desde C++26)ranges::end(r)

Complejidad

1,3) Exactamente ranges::distance(first, last) aplicaciones de f y proj.
2,4) Exactamente ranges::distance(r) aplicaciones de f y proj.

Excepciones

3,4) Durante el proceso de ejecución:
  • Si los recursos de memoria temporal necesarios para la paralelización no están disponibles, std::bad_alloc se lanza.
  • Si se lanza una excepción no capturada al acceder a objetos mediante un argumento de algoritmo, el comportamiento está determinado por la política de ejecución (para políticas estándar, std::terminate se invoca).

Notas

Si la proyección devuelve una referencia mutable, f puede modificar los elementos en el rango destino.

Para las sobrecargas (1,2), f puede ser un objeto invocable con estado. El objeto invocable en el valor devuelto puede considerarse como el estado final de la operación por lotes.

Para las sobrecargas (3,4), se pueden crear múltiples copias de f para realizar la invocación paralela. El valor devuelto no contiene un objeto invocable porque la paralelización a menudo no permite una acumulación eficiente de estado.

Posible implementación

struct for_each_fn
{
    template<std::input_iterator I, std::sentinel_for<I> S, class Proj = std::identity,
             std::indirectly_unary_invocable<std::projected<I, Proj>> Fun>
    constexpr ranges::for_each_result<I, Fun>
        operator()(I first, S last, Fun f, Proj proj = {}) const
    {
        for (; first != last; ++first)
            std::invoke(f, std::invoke(proj, *first));
        return {std::move(first), std::move(f)};
    }
    
    template<ranges::input_range R, class Proj = std::identity,
             std::indirectly_unary_invocable
                 <std::projected<ranges::iterator_t<R>, Proj>> Fun>
    constexpr ranges::for_each_result<ranges::borrowed_iterator_t<R>, Fun>
        operator()(R&& r, Fun f, Proj proj = {}) const
    {
        return (*this)(ranges::begin(r), ranges::end(r), std::move(f), std::ref(proj));
    }
    
    template<ranges::forward_range R, class Proj = std::identity,
             std::indirectly_unary_invocable
                 <std::projected<ranges::iterator_t<R>, Proj>> Fun>
    constexpr ranges::for_each_result<ranges::borrowed_iterator_t<R>, Fun>
        operator()(R&& r, Fun f, Proj proj = {}) const
    {
        return (*this)(ranges::begin(r),
                       ranges::next(ranges::begin(r), ranges::end(r)),
                       std::move(f), std::ref(proj));
    }
};

inline constexpr for_each_fn for_each;

Ejemplo

El siguiente ejemplo usa una expresión lambda para incrementar todos los elementos de un vector y luego usa un operator() sobrecargado en un objeto invocable para calcular su suma. Nótese que para calcular la suma, se recomienda usar el algoritmo dedicado std::accumulate.

#include <algorithm>
#include <cassert>
#include <iostream>
#include <string>
#include <utility>
#include <vector>

struct Sum
{
    void operator()(int n) { sum += n; }
    int sum {0};
};

int main()
{
    namespace ranges = std::ranges;
    
    std::vector<int> nums {3, 4, 2, 8, 15, 267};
    
    auto print = [](const auto& n) { std::cout << ' ' << n; };
    
    std::cout << "before:";
    ranges::for_each(std::as_const(nums), print);
    print('\n');
    
    ranges::for_each(nums, [](int& n) { ++n; });
    
    // calls Sum::operator() for each number
    auto [i, s] = ranges::for_each(nums.begin(), nums.end(), Sum());
    assert(i == nums.end());
    
    std::cout << "after: ";
    ranges::for_each(nums.cbegin(), nums.cend(), print);
    
    std::cout << "\n" "sum: " << s.sum << '\n';
    
    using pair = std::pair<int, std::string>; 
    std::vector<pair> pairs {{1,"one"}, {2,"two"}, {3,"tree"}};
    
    std::cout << "project the pair::first: ";
    ranges::for_each(pairs, print, [](const pair& p) { return p.first; });
    
    std::cout << "\n" "project the pair::second:";
    ranges::for_each(pairs, print, &pair::second);
    print('\n');
}

Salida:

before: 3 4 2 8 15 267 
after:  4 5 3 9 16 268
sum: 305
project the pair::first:  1 2 3
project the pair::second: one two tree

Véase también

aplica un objeto función unariofunction object a elementos de unrango
(plantilla de función)
aplica un objeto función a los primeros N elementos de una secuencia
(objeto función de algoritmo)
aplica una función a un rango de elementos
(objeto función de algoritmo)
rango-for bucle(C++11) ejecuta bucle sobre rango