Namespaces
Variants

std:: transform

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
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 de entrada proporcionado(s), y almacena el resultado en un rango de salida comenzando desde 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 cualquiera de los siguientes rangos, el comportamiento es indefinido:
  • [ first1 , last1 ] .
  • El rango de std:: distance ( first1, last1 ) + 1 elementos comenzando desde 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 comenzando desde first2 .
Si binary_op invalida un iterador o modifica un elemento en cualquiera de los siguientes rangos, el comportamiento es indefinido:
  • [ first1 , last1 ] .
  • El rango de std:: distance ( first1, last1 ) + 1 elementos comenzando desde first2 .
  • El rango de std:: distance ( first1, last1 ) + 1 elementos comenzando desde 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 se cumplen todas las siguientes condiciones:

std:: is_execution_policy_v < std:: decay_t < ExecutionPolicy >> es true .

(hasta C++20)

std:: is_execution_policy_v < std:: remove_cvref_t < ExecutionPolicy >> es true .

(desde C++20)

Contenidos

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 function object unario a elementos de un range
(plantilla de función)
aplica una función a un rango de elementos
(objeto función de algoritmo)