std::for_each
| Definido en el encabezado <algorithm>
|
||
template< class InputIt, class UnaryFunc >
UnaryFunc for_each( InputIt first, InputIt last, UnaryFunc f );
|
(1) | (constexpr desde C++20) |
template< class ExecutionPolicy, class ForwardIt, class UnaryFunc >
void for_each( ExecutionPolicy&& policy,
ForwardIt first, ForwardIt last, UnaryFunc f );
|
(2) | (desde C++17) |
Aplica el objeto invocable dado f a cada elemento en el rango objetivo [first, last). Si f devuelve un resultado, el resultado se ignora.
f se aplica en orden comenzando desde first.
|
Si |
(desde C++11) |
f podría no aplicarse en orden. El algoritmo se ejecuta de acuerdo con policy.for_each no tiene permitido hacer copias arbitrarias de elementos del rango objetivo.true:
|
|
(hasta C++20) |
|
|
(desde C++20) |
UnaryFunc no es CopyConstructible, el comportamiento no está definido.Parámetros
| first, last | - | el par de iteradores que definen el rango objetivorango |
| f | - | objeto función, que se aplicará a los elementos La firma de la función debe ser equivalente a la siguiente:
La firma no necesita tener |
| policy | - | la política de ejecución a utilizar |
| Requisitos de tipo | ||
-InputIt debe cumplir los requisitos de LegacyInputIterator.
| ||
-ForwardIt debe cumplir los requisitos de LegacyForwardIterator.
| ||
Valor devuelto
fComplejidad
Exactamente std::distance(first, last) aplicaciones de f.
Excepciones
- Si los recursos de memoria temporales requeridos para la paralelización no están disponibles, std::bad_alloc se lanza.
- Si se lanza una excepción no capturada mientras se accede a objetos a través de un argumento del algoritmo, el comportamiento está determinado por la política de ejecución (para políticas estándar, std::terminate se invoca).
Notas
Si el tipo de iterador (InputIt/ForwardIt) es mutable, f puede modificar los elementos en el rango objetivo.
Para la sobrecarga (1), f puede ser un objeto invocable con estado. El valor devuelto puede considerarse como el estado final de la operación por lotes.
Para la sobrecarga (2), se pueden crear múltiples copias de f para realizar la invocación paralela. No se devuelve ningún valor porque la paralelización a menudo no permite una acumulación eficiente del estado.
Posible implementación
Véase también las implementaciones en libstdc++, libc++ y 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
}
|
Ejemplo
El siguiente ejemplo utiliza una expresión lambda para incrementar todos los elementos de un vector y luego utiliza un operator() sobrecargado en un objeto invocable para calcular su suma. Note que para calcular la suma, se recomienda usar el algoritmo dedicado 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';
}
Salida:
before: 3 -4 2 -8 15 267
after: 4 -3 3 -7 16 268
sum: 281
Informes de defectos
Los siguientes informes de defectos que cambian el comportamiento se aplicaron retroactivamente a estándares C++ previamente publicados.
| DR | Aplicado a | Comportamiento como se publicó | Comportamiento correcto |
|---|---|---|---|
| LWG 475 | C++98 | no estaba claro si f puede modificar los elementosde la secuencia que se está iterando ( for_each estáclasificado como “operaciones de secuencia no modificadoras”) |
se aclaró (permitido si el tipo de iterador es mutable) |
| LWG 2747 | C++11 | la sobrecarga (1) devolvía std::move(f)
|
devuelve f (que se mueve implícitamente)
|
Véase también
(C++20) |
aplica un objeto función unario a elementos de un rango (objeto función de algoritmo) |
(C++17) |
aplica un objeto función a los primeros N elementos de una secuencia (plantilla de función & objeto función de algoritmo) |
(C++20) |
|
| aplica una función a un rango de elementos, almacenando los resultados en un rango de destino (plantilla de función & objeto función de algoritmo) | |
(C++20) |
|
bucle- for for basado en rango(C++11)
|
ejecuta un bucle sobre un rango |