Namespaces
Variants

std::transform

De es.cppreference.net
 
 
Biblioteca de algoritmos
Algoritmos restringidos y algoritmos sobre rangos (C++20)
Algoritmos restringidos, por ejemplo 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)

Ordenación y operaciones relacionadas
Operaciones de particionado
(C++11)    

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


 
Definido en el encabezado <algorithm>
template< class InputIt, class OutputIt, class UnaryOp >
OutputIt transform( InputIt first1, InputIt last1,
                    OutputIt d_first, UnaryOp unary_op );
(1) (constexpr desde C++20)
template< class ExecutionPolicy,
          class ForwardIt1, class ForwardIt2, class UnaryOp >
ForwardIt2 transform( ExecutionPolicy&& policy,
                      ForwardIt1 first1, ForwardIt1 last1,
                      ForwardIt2 d_first, UnaryOp unary_op );
(2) (desde C++17)
template< class InputIt1, class InputIt2,
          class OutputIt, class BinaryOp >
OutputIt transform( InputIt1 first1, InputIt1 last1, InputIt2 first2,
                    OutputIt d_first, BinaryOp binary_op );
(3) (constexpr desde C++20)
template< class ExecutionPolicy,
          class ForwardIt1, class ForwardIt2,
          class ForwardIt3, class BinaryOp >
ForwardIt3 transform( ExecutionPolicy&& policy,
                      ForwardIt1 first1, ForwardIt1 last1,
                      ForwardIt2 first2,
                      ForwardIt3 d_first, BinaryOp binary_op );
(4) (desde C++17)

std::transform aplica la función dada a los elementos del rango(s) de entrada dado(s), y almacena el resultado en un rango de salida que comienza en d_first.

1) La operación unaria unary_op se aplica a los elementos de [first1, last1).
Si unary_op invalida un iterador o modifica un elemento en alguno de los siguientes rangos, el comportamiento no está definido:
  • [first1, last1].
  • El rango de std::distance(first1, last1) + 1 elementos que comienza en d_first.
3) La operación binaria binary_op se aplica a pares de elementos de dos rangos: [first1, last1) y otro rango de std::distance(first1, last1) elementos que comienza en first2.
Si binary_op invalida un iterador o modifica un elemento en alguno de los siguientes rangos, el comportamiento no está definido:
  • [first1, last1].
  • El rango de std::distance(first1, last1) + 1 elementos que comienza en first2.
  • El rango de std::distance(first1, last1) + 1 elementos que comienza en d_first.
2,4) Igual que (1,3), pero ejecutado de acuerdo con policy.
Estas sobrecargas participan en la resolución de sobrecarga solo si el valor de la siguiente expresión es true:

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>

(hasta C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>

(desde C++20)

Parámetros

first1, last1 - el par de iteradores que define el rango fuente de elementos a transformar
first2 - el inicio del segundo rango de elementos a transformar, ( 3,4 ) solamente
d_first - el inicio del rango destino, puede ser igual a first1 o first2
policy - la política de ejecución a utilizar
unary_op - objeto función de operación unaria que será aplicado.

La firma de la función debe ser equivalente a la siguiente:

Ret fun ( const Type & a ) ;

La firma no necesita tener const & .
El tipo Type debe ser tal que un objeto de tipo InputIt pueda ser desreferenciado y luego convertido implícitamente a Type . El tipo Ret debe ser tal que un objeto de tipo OutputIt pueda ser desreferenciado y asignado un valor de tipo Ret . ​

binary_op - objeto función de operación binaria que será aplicado.

La firma de la función debe ser equivalente a la siguiente:

Ret fun ( const Type1 & a, const Type2 & b ) ;

La firma no necesita tener const & .
Los tipos Type1 y Type2 deben ser tales que objetos de tipos InputIt1 y InputIt2 puedan ser desreferenciados y luego convertidos implícitamente a Type1 y Type2 respectivamente. El tipo Ret debe ser tal que un objeto de tipo OutputIt pueda ser desreferenciado y asignado un valor de tipo Ret . ​

Requisitos de tipo
-
InputIt, InputIt1, InputIt2 deben cumplir con los requisitos de LegacyInputIterator .
-
OutputIt deben cumplir con los requisitos de LegacyOutputIterator .
-
ForwardIt1, ForwardIt2, ForwardIt3 deben cumplir con los requisitos de LegacyForwardIterator .

Valor de retorno

Iterador de salida al elemento que sigue al último elemento transformado.

Complejidad

Dado N como std:: distance ( first1, last1 ) :

1,2) Exactamente N aplicaciones de unary_op .
3,4) Exactamente N aplicaciones de binary_op .

Excepciones

Las sobrecargas con un parámetro de plantilla llamado ExecutionPolicy reportan errores de la siguiente manera:

  • Si la ejecución de una función invocada como parte del algoritmo lanza una excepción y ExecutionPolicy es uno de los standard policies , std::terminate es llamado. Para cualquier otro ExecutionPolicy , el comportamiento está definido por la implementación.
  • Si el algoritmo falla al asignar memoria, std::bad_alloc es lanzado.

Implementación posible

transform (1)
template<class InputIt, class OutputIt, class UnaryOp>
constexpr //< since C++20
OutputIt transform(InputIt first1, InputIt last1,
                   OutputIt d_first, UnaryOp unary_op)
{
    for (; first1 != last1; ++d_first, ++first1)
        *d_first = unary_op(*first1);
    return d_first;
}
transform (3)
template<class InputIt1, class InputIt2, 
         class OutputIt, class BinaryOp>
constexpr //< since C++20
OutputIt transform(InputIt1 first1, InputIt1 last1, InputIt2 first2,
                   OutputIt d_first, BinaryOp binary_op)
{
    for (; first1 != last1; ++d_first, ++first1, ++first2)
        *d_first = binary_op(*first1, *first2);
    return d_first;
}

Notas

std::transform no garantiza la aplicación en orden de unary_op o binary_op . Para aplicar una función a una secuencia en orden o para aplicar una función que modifique los elementos de una secuencia, use std::for_each .

Ejemplo

#include <algorithm>
#include <cctype>
#include <iomanip>
#include <iostream>
#include <string>
#include <utility>
#include <vector>
void print_ordinals(const std::vector<unsigned>& ordinals)
{
    std::cout << "ordinals: ";
    for (unsigned ord : ordinals)
        std::cout << std::setw(3) << ord << ' ';
    std::cout << '\n';
}
char to_uppercase(unsigned char c)
{
    return std::toupper(c);
}
void to_uppercase_inplace(char& c)
{
    c = to_uppercase(c);
}
void unary_transform_example(std::string& hello, std::string world)
{
    // Transformar cadena a mayúsculas in situ
    std::transform(hello.cbegin(), hello.cend(), hello.begin(), to_uppercase);
    std::cout << "hello = " << std::quoted(hello) << '\n';
    // versión for_each (ver Notas arriba)
    std::for_each(world.begin(), world.end(), to_uppercase_inplace);
    std::cout << "world = " << std::quoted(world) << '\n';
}
void binary_transform_example(std::vector<unsigned> ordinals)
{
    // Transformar números a valores duplicados
    print_ordinals(ordinals);
    std::transform(ordinals.cbegin(), ordinals.cend(), ordinals.cbegin(),
                   ordinals.begin(), std::plus<>{});
    print_ordinals(ordinals);
}
int main()
{
    std::string hello("hello");
    unary_transform_example(hello, "world");
    std::vector<unsigned> ordinals;
    std::copy(hello.cbegin(), hello.cend(), std::back_inserter(ordinals));
    binary_transform_example(std::move(ordinals));
}

Salida:

hello = "HELLO"
world = "WORLD"
ordinals:  72  69  76  76  79 
ordinals: 144 138 152 152 158

Informes de defectos

Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.

DR Aplicado a Comportamiento publicado Comportamiento correcto
LWG 242 C++98 unary_op y binary_op no podían tener efectos secundarios no pueden modificar los rangos involucrados

Véase también

aplica un unario objeto función a elementos de un rango
(plantilla de función & objeto función de algoritmo)
aplica una función a un rango de elementos
(objeto función de algoritmo)