std::ranges::for_each, std::ranges::for_each_result
Definido en el archivo de encabezado <algorithm> | ||
Signatura de la llamada | ||
template<std::input_iterator I, std::sentinel_for<I> S, class Proj =std::identity, std::indirectly_unary_invocable<std::projected<I, Proj>> Fun > | (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 > | (2) | (desde C++20) |
Tipos auxiliares | ||
template<class I, class F > using for_each_result =ranges::in_fun_result<I, F>; | (3) | (desde C++20) |
f
al resultado del valor proyectado por cada iterador en el rango [first, last), en orden. r
como el rango fuente, como si usara ranges::begin(r) como first
y ranges::end(r) como last
.Para ambas sobrecargas, si el tipo de iterador es mutable, f
puede modificar los elementos del rango a través del iterador desreferenciado. Si f
devuelve un resultado, el resultado se ignora.
Las entidades similares a funciones descritas en esta página son niebloids, es decir:
- Las listas de argumentos de plantilla explícitas no se pueden especificar al llamar a cualquiera de ellas.
- Ninguna de ellas es visible para la búsqueda dependiente de argumentos.
- Cuando alguna de ellas se encuentra mediante la búsqueda normal no calificada como el nombre a la izquierda del operador de llamada a función, se inhibe la búsqueda dependiente de argumentos.
En la práctica, pueden implementarse como objetos función o con extensiones de compilador especiales.
Contenido |
[editar]Parámetros
first, last | - | Par iterador-centinela que denota el rango a aplicar a la función. |
r | - | El rango de elementos a los que aplicar la función. |
f | - | La función a aplicar al rango proyectado. |
proj | - | Proyección a aplicar a los elementos. |
[editar]Valor de retorno
{std::ranges::next(std::move(first), last), std::move(f)}
[editar]Complejidad
Exactamente last
- first
aplicaciones de f
y proj
.
[editar]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));}}; inlineconstexpr for_each_fn for_each; |
[editar]Ejemplo
El siguiente ejemplo usa una expresión lambda para incrementar todos los elementos de un vector y luego usa un operador operator()
sobrecargado en un objeto función para calcular su suma. Ten en cuenta que para calcular la suma, se recomienda utilizar el algoritmo dedicado std::accumulate.
#include <algorithm>#include <cassert>#include <iostream>#include <string>#include <utility>#include <vector> struct Suma {void operator()(int n){ suma += n;}int suma{0};}; int main(){std::vector<int> nums{3, 4, 2, 8, 15, 267}; auto imprimir =[](constauto& n){std::cout<<' '<< n;}; namespace ranges = std::ranges;std::cout<<"antes:"; ranges::for_each(std::as_const(nums), imprimir); imprimir('\n'); ranges::for_each(nums, [](int& n){++n;}); // llama a Suma::operator() para cada númeroauto[i, s]= ranges::for_each(nums.begin(), nums.end(), Suma());assert(i == nums.end()); std::cout<<"después: "; ranges::for_each(nums.cbegin(), nums.cend(), imprimir); std::cout<<"\n""suma: "<< s.suma<<'\n'; using Par =std::pair<int, std::string>;std::vector<Par> pares{{1,"uno"}, {2,"dos"}, {3,"tres"}}; std::cout<<"proyectar el elemento Par::first: "; ranges::for_each(pares, imprimir, [](const Par& p){return p.first;}); std::cout<<"\n""proyectar el elemento Par::second:"; ranges::for_each(pares, imprimir, &Par::second); imprimir('\n');}
Salida:
antes: 3 4 2 8 15 267 después: 4 5 3 9 16 268 suma: 305 proyectar el elemento Par::first: 1 2 3 proyectar el elemento Par::second: uno dos tres
[editar]Véase también
Bucle for basado en rango | Ejecuta un bucle sobre un rango (desde C++11) |
(C++20) | Aplica una función a un rango de elementos. (niebloid) |
(C++20) | Aplica un objeto función a los primeros n elementos de una secuencia. (niebloid) |
Aplica una función a un rango de elementos. (plantilla de función) |