std::transform
Определено в заголовке <algorithm> | ||
|---|---|---|
template< class InputIt, class OutputIt, class UnaryOp >
OutputIt transform( InputIt first1, InputIt last1,
OutputIt d_first, UnaryOp unary_op );
| (1) | (constexpr с C++20) |
template< class InputIt1, class InputIt2,
class OutputIt, class BinaryOp >
OutputIt transform( InputIt1 first1, InputIt1 last1, InputIt2 first2,
OutputIt d_first, BinaryOp binary_op );
| (2) | (constexpr с 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 );
| (3) | (с C++17) |
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) | (с C++17) |
Пусть count равно std::distance(first1, last1). Применяет заданную функцию к элементам заданного исходного диапазона (или диапазонов) и сохраняет результат в целевом диапазоне [d_first, std::next(d_first, count)).
[first1, last1), и унарная операция unary_op применяется к каждому из его элементов.unary_op делает недействительным итератор или изменяет элемент в любом из следующих диапазонов, поведение не определено: -
[first1,last1] -
[d_first,std::next(d_first, count)]
[first1, last1) и [first2, std::next(first2, count)), и бинарная операция binary_op применяется к каждой паре соответствующих элементов.binary_op делает недействительным итератор или изменяет элемент в любом из следующих диапазонов, поведение не определено: -
[first1,last1] -
[first2,std::next(first2, count)] -
[d_first,std::next(d_first, count)]
policy.true: |
| (до C++20) |
|
| (с C++20) |
Параметры
| first1, last1 | - | пара итераторов, определяющая первый исходный диапазон |
| first2 | - | начало второго исходного диапазона |
| d_first | - | начало целевого диапазона |
| unary_op | - | функциональный объект унарной операции, которая будет применяться. Сигнатура функции должна быть эквивалентна следующей: Retfun(constType&a); Сигнатура не обязательно должна содержать |
| binary_op | - | функциональный объект бинарной операции, которая будет применяться. Сигнатура функции должна быть эквивалентна следующей: Retfun(constType1&a,constType2&b); Сигнатура не обязательно должна содержать |
| policy | - | используемая политика выполнения |
| Требования к типам | ||
-InputIt, InputIt1, InputIt2 должен соответствовать требованиям LegacyInputIterator. |
||
-OutputIt должен соответствовать требованиям LegacyOutputIterator. |
||
-ForwardIt1, ForwardIt2, ForwardIt3 должен соответствовать требованиям LegacyForwardIterator. |
||
Возвращаемое значение
Итератор, указывающий за пределы последнего элемента целевого диапазона (past-the-end).
Сложность
Пусть \(\scriptsize N\)N равно std::distance(first1, last1):
unary_op.binary_op.Исключения
3,4) В процессе выполнения:- Если временные ресурсы памяти, необходимые для параллелизации, недоступны, выбрасывается
std::bad_alloc. - Если при доступе к объектам через аргумент алгоритма выбрасывается неперехваченное исключение, поведение определяется политикой выполнения (для стандартных политик вызывается
std::terminate).
Возможная реализация
| 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 (2) |
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;
}
|
Примечания
std::transform не гарантирует последовательное применение unary_op или binary_op по порядку. Для применения функции к последовательности по порядку или для применения функции, которая изменяет элементы последовательности, используйте std::for_each.
Пример
#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);
}
// Transform string to uppercase in-place
void unary_transform_example(std::string& hello, std::string world)
{
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';
}
// Transform numbers to doubled values
void binary_transform_example(std::vector<unsigned> ordinals)
{
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));
}
Вывод:
hello = "HELLO" world = "WORLD" ordinals: 72 69 76 76 79 ordinals: 144 138 152 152 158
Отчёты об ошибках
Следующие отчёты об ошибках, изменяющие поведение, были применены задним числом к ранее опубликованным стандартам C++.
| Дефект | Применён к | Поведение согласно публикации | Исправленное поведение |
|---|---|---|---|
| LWG 242 | C++98 |
unary_op и binary_op не могли иметь побочных эффектов | они не могут изменять задействованные диапазоны |
Смотрите также
|
(C++20) | применяет функцию к диапазону элементов (функциональный объект алгоритма) |
| применяет унарный функциональный объект к элементам из диапазона (шаблон функции и функциональный объект алгоритма) |
|
|
(C++20) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/algorithm/transform