std::transform() algorithm
- od C++20
- od C++17
- do C++17
// (1)
template< class InputIt, class OutputIt, class UnaryOperation >
constexpr OutputIt transform( InputIt first1, InputIt last1,
OutputIt d_first, UnaryOperation unary_op );
// (2)
template< class InputIt1, class InputIt2,
class OutputIt, class BinaryOperation >
constexpr OutputIt transform( InputIt1 first1, InputIt1 last1, InputIt2 first2,
OutputIt d_first, BinaryOperation binary_op );
// (3)
template< class ExecutionPolicy, class ForwardIt1,
class ForwardIt2, class UnaryOperation >
ForwardIt2 transform( ExecutionPolicy&& policy,
ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 d_first, UnaryOperation unary_op );
// (4)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2,
class ForwardIt3, class BinaryOperation >
ForwardIt3 transform( ExecutionPolicy&& policy,
ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2,
ForwardIt3 d_first, BinaryOperation binary_op );
// (1)
template< class InputIt, class OutputIt, class UnaryOperation >
OutputIt transform( InputIt first1, InputIt last1,
OutputIt d_first, UnaryOperation unary_op );
// (2)
template< class InputIt1, class InputIt2,
class OutputIt, class BinaryOperation >
OutputIt transform( InputIt1 first1, InputIt1 last1, InputIt2 first2,
OutputIt d_first, BinaryOperation binary_op );
// (3)
template< class ExecutionPolicy, class ForwardIt1,
class ForwardIt2, class UnaryOperation >
ForwardIt2 transform( ExecutionPolicy&& policy,
ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 d_first, UnaryOperation unary_op );
// (4)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2,
class ForwardIt3, class BinaryOperation >
ForwardIt3 transform( ExecutionPolicy&& policy,
ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2,
ForwardIt3 d_first, BinaryOperation binary_op );
// (1)
template< class InputIt, class OutputIt, class UnaryOperation >
OutputIt transform( InputIt first1, InputIt last1,
OutputIt d_first, UnaryOperation unary_op );
// (2)
template< class InputIt1, class InputIt2,
class OutputIt, class BinaryOperation >
OutputIt transform( InputIt1 first1, InputIt1 last1, InputIt2 first2,
OutputIt d_first, BinaryOperation binary_op );
Applies the given function to a range and stores the result in another range, keeping the original elements order and beginning at d_first
.
-
(1) The unary operation
unary_op
is applied to the range defined by [ first1; last1 ). -
(2) The binary operation
binary_op
is applied to pairs of elements from two ranges:- one defined by [
first1
;last1
) - other beginning at
first2
.
- one defined by [
-
(3, 4) Same as (1) and (2), but executed according to policy.
Overload ResolutionThese overloads participate in overload resolution only if
std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>
istrue
. (do C++20)std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>
istrue
. (od C++20)
unary_op
and binary_op
must not invalidate any iterators, including the end iterators, or modify any elements of the ranges involved.
Parameters
first1 last | The first range of elements to transform. |
first2 | The beginning of the second range of elements to transform. |
d_first | The beginning of the destination range, may be equal to |
policy | The execution policy to use. See execution policy for details. |
unary_op | Unary operation function object that will be applied. The signature of the function should be equivalent to the following:
|
unary_op | Binary operation function object that will be applied. The signature of the function should be equivalent to the following:
|
Type requirements
InputIt InputIt1 InputIt2 | LegacyInputIterator |
OutputIt | LegacyOutputIterator |
ForwardIt1 ForwardIt2 ForwardIt3 | LegacyForwardIterator |
Return value
Output iterator to the element that follows the last element transformed.
Complexity
- (1, 3) Exactly
std::distance(first1, last1)
applications ofunary_op
. - (2, 4) Exactly
std::distance(first1, last1)
applications ofunary_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
ExecutionPolicy
is 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 UnaryOperation >
OutputIt transform( InputIt first1, InputIt last1, OutputIt d_first, UnaryOperation unary_op )
{
while (first1 != last1)
*d_first++ = unary_op(*first1++);
return d_first;
}
transform (2)
template< class InputIt1, class InputIt2, class OutputIt, class BinaryOperation >
OutputIt transform(InputIt1 first1, InputIt1 last1,
InputIt2 first2, OutputIt d_first,
BinaryOperation binary_op)
{
while (first1 != last1)
*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
.
Examples
The following code uses transform
to convert a string in place to uppercase using the std::toupper
function and then transforms each char to its ordinal value.
Then transform
with a projection is used to transform elements of std::vector<Foo>
into chars to fill a std::string
.
The following code uses transform to convert a string in place to uppercase using the std::toupper
function and then transforms each char to its ordinal value:
#include <algorithm>
#include <cctype>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
void print_ordinals(std::vector<std::size_t> const& ordinals)
{
std::cout << "ordinals: ";
for (std::size_t ord : ordinals)
std::cout << std::setw(3) << ord << ' ';
std::cout << '\n';
}
int main()
{
std::string s {"hello"};
std::transform(s.cbegin(), s.cend(),
s.begin(), // write to the same location
[](unsigned char c) { return std::toupper(c); });
std::cout << "s = " << std::quoted(s) << '\n';
// achieving the same with std::for_each (see Notes above)
std::string g {"hello"};
std::for_each(g.begin(), g.end(), [](char& c) // modify in-place
{
c = std::toupper(static_cast<unsigned char>(c));
});
std::cout << "g = " << std::quoted(g) << '\n';
std::vector<std::size_t> ordinals;
std::transform(s.cbegin(), s.cend(), std::back_inserter(ordinals),
[](unsigned char c) { return c; });
print_ordinals(ordinals);
std::transform(ordinals.cbegin(), ordinals.cend(), ordinals.cbegin(),
ordinals.begin(), std::plus<>{});
print_ordinals(ordinals);
}
s = "HELLO"
g = "HELLO"
ordinals: 72 69 76 76 79
ordinals: 144 138 152 152 158
Hover to see the original license.