Espacios de nombres
Variantes
Acciones

std::ranges::transform, std::ranges::unary_transform_result, std::ranges::binary_transform_result

De cppreference.com
< cpp‎ | algorithm‎ | ranges
 
 
Biblioteca de algoritmos
Políticas de ejecución (C++17)
Operaciones de secuencia no modificantes
(C++11)(C++11)(C++11)
(C++17)
Operaciones de secuencia modificantes
Operaciones en almacenamiento no inicializado
Operaciones de partición
Operaciones de ordenación
Operaciones de búsqueda binaria
Operaciones de conjuntos (en rangos ordenados)
Operaciones de pila
(C++11)
Operaciones mínimo/máximo
(C++11)
(C++17)
Permutaciones
Operaciones numéricas
Bibliotecas C
 
Algoritmos restringidos
Operaciones de secuencia no modificantes
Operaciones de secuencia modificantes
Operaciones en almacenamiento sin inicializar
Operaciones de partición
Operaciones de ordenamiento
Operaciones de búsqueda binaria
Operaciones de conjuntos (en rangos ordenados)
Operaciones de montículo/montón
Operaciones de mínimo/máximo
Permutaciones
 
Definido en el archivo de encabezado <algorithm>
Signatura de la llamada
template<std::input_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O,

          std::copy_constructible F, class Proj =std::identity>
requires std::indirectly_writable<O,
                                  std::indirect_result_t<F&, std::projected<I, Proj>>>
constexpr unary_transform_result<I, O>

    transform( I first1, S last1, O result, F op, Proj proj ={});
(1) (desde C++20)
template<ranges::input_range R, std::weakly_incrementable O,

          std::copy_constructible F, class Proj =std::identity>
requires std::indirectly_writable<O,
             std::indirect_result_t<F&, std::projected<ranges::iterator_t<R>, Proj>>>
constexpr unary_transform_result<ranges::borrowed_iterator_t<R>, O>

    transform( R&& r, O result, F op, Proj proj ={});
(2) (desde C++20)
template<std::input_iterator I1, std::sentinel_for<I1> S1,

          std::input_iterator I2, std::sentinel_for<I2> S2,
          std::weakly_incrementable O,
          std::copy_constructible F,
          class Proj1 =std::identity, class Proj2 =std::identity>
requires std::indirectly_writable<O,
             std::indirect_result_t<F&,
                                    std::projected<I1, Proj1>,
                                    std::projected<I2, Proj2>>>
constexpr binary_transform_result<I1, I2, O>
    transform( I1 first1, S1 last1, I2 first2, S2 last2, O result,

               F binary_op, Proj1 proj1 ={}, Proj2 proj2 ={});
(3) (desde C++20)
template<ranges::input_range R1,

          ranges::input_range R2,
          std::weakly_incrementable O,
          std::copy_constructible F,
          class Proj1 =std::identity, class Proj2 =std::identity>
requires std::indirectly_writable<O,
             std::indirect_result_t<F&,
                 std::projected<ranges::iterator_t<R1>, Proj1>,
                 std::projected<ranges::iterator_t<R2>, Proj2>>>
constexpr binary_transform_result<ranges::borrowed_iterator_t<R1>,
                                  ranges::borrowed_iterator_t<R2>, O>
    transform( R1&& r1, R2&& r2, O result, F binary_op,

               Proj1 proj1 ={}, Proj2 proj2 ={});
(4) (desde C++20)
Tipos auxiliares
template<class I, class O >
using unary_transform_result =ranges::in_out_result<I, O>;
(5) (desde C++20)
template<class I1, class I2, class O >
using binary_transform_result =ranges::in_in_out_result<I1, I2, O>;
(6) (desde C++20)

Aplica la función dada a un rango y almacena el resultado en otro rango que comienza en result.

1) La operación unaria op se aplica al rango definido por [first1last1) (después de proyectar con la proyección proj).
2) Igual que (1), pero usa r como el rango fuente, como si usara ranges::begin(r) como first y ranges::end(r) como last.
3) La operación binaria binary_op se aplica a los pares de elementos de dos rangos: uno definido por [first1last1) y el otro definido por [first2last2) (después de proyectar respectivamente con las proyecciones proj1 y proj2).
4) Igual que (3), pero usa r1 como el primer rango fuente, como si usara ranges::begin(r1) como first1 y ranges::end(r1) como last1, y de manera similar para r2.

Las entidades similares a funciones descritas en esta página son niebloids, es decir:

En la práctica, pueden implementarse como objetos función o con extensiones de compilador especiales.

Contenido

[editar]Parámetros

first1, last1 - El primer rango de elementos a transformar.
r, r1 - El primer rango de elementos a transformar.
first2, last2 - El segundo rango de elementos a transformar.
r2 - El segundo rango de elementos a transformar.
result - El comienzo del rango de destino, puede ser igual a first1 o first2
op, binary_op - La operación a aplicar a los elementos proyectados.
proj1 - La proyección a aplicar a los elementos en el primer rango.
proj2 - La proyección a aplicar a los elementos en el segundo rango.

[editar]Valor de retorno

1-2) Un resultado de tipo unary_transform_result que contiene un iterador de entrada igual a last y un iterador de salida al elemento más allá del último elemento transformado.
3-4) Un resultado de tipo binary_transform_result que contiene iteradores de entrada a los últimos elementos transformados de los rangos [first1last1) y [first2last2) como in1 e in2 respectivamente, y el iterador de salida al elemento más allá del último elemento transformado como out.

[editar]Complejidad

1,2) Exactamente ranges::distance(first1, last1) aplicaciones de op y proj.
3,4) Exactamente ranges::min(ranges::distance(first1, last1), ranges::distance(first2, last2)) aplicaciones de binary_op y las proyecciones.

[editar]Posible implementación

struct transform_fn {// Primera versióntemplate<std::input_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O, std::copy_constructible F, class Proj =std::identity> requires std::indirectly_writable<O, std::indirect_result_t<F&, std::projected<I, Proj>>>constexpr ranges::unary_transform_result<I, O> operator()(I first1, S last1, O result, F op, Proj proj ={})const{for(; first1 != last1;++first1, (void)++result)*result =std::invoke(op, std::invoke(proj, *first1));   return{first1, result};}   // Segunda versióntemplate<ranges::input_range R, std::weakly_incrementable O, std::copy_constructible F, class Proj =std::identity> requires std::indirectly_writable<O, std::indirect_result_t<F&, std::projected<ranges::iterator_t<R>, Proj>>>constexpr ranges::unary_transform_result<ranges::borrowed_iterator_t<R>, O> operator()(R&& r, O result, F op, Proj proj ={})const{return(*this)(ranges::begin(r), ranges::end(r), result, std::ref(op), std::ref(proj));}   // Tercera versióntemplate<std::input_iterator I1, std::sentinel_for<I1> S1, std::input_iterator I2, std::sentinel_for<I2> S2, std::weakly_incrementable O, std::copy_constructible F, class Proj1 =std::identity, class Proj2 =std::identity> requires std::indirectly_writable<O, std::indirect_result_t<F&, std::projected<I1, Proj1>, std::projected<I2, Proj2>>>constexpr ranges::binary_transform_result<I1, I2, O> operator()(I1 first1, S1 last1, I2 first2, S2 last2, O result, F binary_op, Proj1 proj1 ={}, Proj2 proj2 ={})const{for(; first1 != last1 && first2 != last2;++first1, (void)++first2, (void)++result)*result =std::invoke(binary_op, std::invoke(proj1, *first1), std::invoke(proj2, *first2));   return{first1, first2, result};}   // Cuarta versióntemplate<ranges::input_range R1, ranges::input_range R2, std::weakly_incrementable O, std::copy_constructible F, class Proj1 =std::identity, class Proj2 =std::identity> requires std::indirectly_writable<O, std::indirect_result_t<F&, std::projected<ranges::iterator_t<R1>, Proj1>, std::projected<ranges::iterator_t<R2>, Proj2>>>constexpr ranges::binary_transform_result<ranges::borrowed_iterator_t<R1>, ranges::borrowed_iterator_t<R2>, O> operator()(R1&& r1, R2&& r2, O result, F binary_op, Proj1 proj1 ={}, Proj2 proj2 ={})const{return(*this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), result, std::ref(binary_op), std::ref(proj1), std::ref(proj2));}};   inlineconstexpr transform_fn transform;

[editar]Notas

ranges::transform no garantiza la aplicación en orden de op o binary_op. Para aplicar una función a una secuencia en orden o para aplicar una función que modifica los elementos de una secuencia, utiliza ranges::for_each.

[editar]Ejemplo

El siguiente código usa ranges::transform para convertir una cadena en su lugar a mayúsculas usando la función std::toupper y luego transforma cada char a su valor ordinal. Luego ranges::transform con una proyección se usa para transformar elementos de std::vector<Foo> en caracteres para llenar una cadena de tipo std::string.

#include <algorithm>#include <cctype>#include <functional>#include <iostream>#include <string>#include <vector>   int main(){std::string s {"hola"};   namespace ranges = std::ranges;   ranges::transform(s.begin(), s.end(), s.begin(), [](unsignedchar c)->unsignedchar{returnstd::toupper(c);});   std::vector<std::size_t> ordinals; ranges::transform(s, std::back_inserter(ordinals), [](unsignedchar c)->std::size_t{return c;});   std::cout<< s <<':';for(auto ord : ordinals)std::cout<<' '<< ord;   ranges::transform(ordinals, ordinals, ordinals.begin(), std::plus{});   std::cout<<'\n';for(auto ord : ordinals)std::cout<< ord <<' ';std::cout<<'\n';   struct Foo {char bar;};conststd::vector<Foo> f ={{'h'},{'o'},{'l'},{'a'}};std::string bar; ranges::transform(f, std::back_inserter(bar), &Foo::bar);std::cout<< bar <<'\n';}

Salida:

HOLA: 72 79 76 65 144 158 152 130 hola

[editar]Véase también

Aplica una función a un rango de elementos.
(niebloid)[editar]
Una vista (view) de una secuencia que aplica una función de transformación a cada elemento.
(plantilla de clase)(objeto adaptador de rango)[editar]
Aplica una función a un rango de elementos
(plantilla de función)[editar]
close