std::ranges::for_each, std::ranges::for_each_result
| 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 [first, last) o r. Si f devuelve un resultado, se ignora.
f se aplica en orden desde el inicio del rango objetivo.f podría no aplicarse en orden. El algoritmo se ejecuta de acuerdo con policy.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:
- No se pueden especificar listas de argumentos de plantilla explícitas al llamar a cualquiera de ellas.
- Ninguna de ellas es visible a la búsqueda dependiente de argumentos.
- Cuando cualquiera de ellas se encuentra mediante búsqueda no calificada normal como el nombre a la izquierda del operador de llamada a función, la búsqueda dependiente de argumentos se inhibe.
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
{last, std::move(f)}{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)}lastranges::next(ranges::begin(r), ranges::end(r)) si R modela forward_range, de lo contrario (desde C++26)ranges::end(r)Complejidad
ranges::distance(first, last) aplicaciones de f y proj.ranges::distance(r) aplicaciones de f y proj.Excepciones
- 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) | |
(C++20) |
aplica un objeto función a los primeros N elementos de una secuencia (objeto función de algoritmo) |
(C++20) |
aplica una función a un rango de elementos (objeto función de algoritmo) |
rango-for bucle(C++11)
|
ejecuta bucle sobre rango |