std::transform
| Defined in header <algorithm>
|
||
template< class InputIt, class OutputIt, class UnaryOp > OutputIt transform( InputIt first1, InputIt last1, OutputIt d_first, UnaryOp unary_op ); |
(1) | (constexpr since 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) | (since 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 since 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) | (since C++17) |
std::transform applies the given function to the elements of the given input range(s), and stores the result in an output range starting from d_first.
unary_op is applied to the elements of [first1, last1).unary_op invalidates an iterator or modifies an element in any of the following ranges, the behavior is undefined:
[first1,last1].- The range of
std::distance(first1, last1) + 1elements starting fromd_first.
binary_op is applied to pairs of elements from two ranges: [first1, last1) and another range of std::distance(first1, last1) elements starting from first2.binary_op invalidates an iterator or modifies an element in any of the following ranges, the behavior is undefined:
[first1,last1].- The range of
std::distance(first1, last1) + 1elements starting fromfirst2. - The range of
std::distance(first1, last1) + 1elements starting fromd_first.
policy.|
|
(until C++20) |
|
|
(since C++20) |
Parameters
| first1, last1 | - | the pair of iterators defining the source range of elements to transform |
| first2 | - | the beginning of the second range of elements to transform, (3,4) only |
| d_first | - | the beginning of the destination range, may be equal to first1 or first2
|
| policy | - | the execution policy to use |
| unary_op | - | unary operation function object that will be applied. The signature of the function should be equivalent to the following:
The signature does not need to have |
| binary_op | - | binary operation function object that will be applied. The signature of the function should be equivalent to the following:
The signature does not need to have |
| Type requirements | ||
-InputIt, InputIt1, InputIt2 must meet the requirements of LegacyInputIterator.
| ||
-OutputIt must meet the requirements of LegacyOutputIterator.
| ||
-ForwardIt1, ForwardIt2, ForwardIt3 must meet the requirements of LegacyForwardIterator.
| ||
Return value
Output iterator to the element that follows the last element transformed.
Complexity
Given N as std::distance(first1, last1):
unary_op.binary_op.Exceptions
The overloads with a template parameter named ExecutionPolicy report errors as follows:
- If execution of a function invoked as part of the algorithm throws an exception and
ExecutionPolicyis one of the standard policies, std::terminate is called. For any otherExecutionPolicy, the behavior is implementation-defined. - If the algorithm fails to allocate memory, std::bad_alloc is thrown.
Possible implementation
| 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;
}
|
Notes
std::transform does not guarantee in-order application of unary_op or binary_op. To apply a function to a sequence in-order or to apply a function that modifies the elements of a sequence, use std::for_each.
Example
#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)
{
// Transform string to uppercase in-place
std::transform(hello.cbegin(), hello.cend(), hello.begin(), to_uppercase);
std::cout << "hello = " << std::quoted(hello) << '\n';
// for_each version (see Notes above)
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)
{
// Transform numbers to doubled values
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));
}
Output:
hello = "HELLO"
world = "WORLD"
ordinals: 72 69 76 76 79
ordinals: 144 138 152 152 158
Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| LWG 242 | C++98 | unary_op and binary_op could not have side effects
|
they cannot modify the ranges involved |
See also
| applies a unary function object to elements from a range (function template) | |
(C++20) |
applies a function to a range of elements (algorithm function object) |