Namespaces
Variants

std::transform

С ru.cppreference.net
 
 
Библиотека алгоритмов
Ограниченные алгоритмы и алгоритмы для диапазонов (C++20)
Ограниченные алгоритмы, например ranges::copy, ranges::sort, ...
Неизменяющие операции с последовательностями    
Пакетные операции
(C++17)
Операции поиска
Изменяющие операции с последовательностями
Операции копирования
(C++11)
(C++11)
Операции обмена
Операции преобразования
Операции генерации
Операции удаления
Операции изменения порядка
(до C++17)(C++11)
(C++20)(C++20)
Операции выборки
(C++17)

Сортировка и связанные операции
Операции разделения
(C++11)    

Операции сортировки
Операции двоичного поиска
(по разбитым диапазонам)
Операции над множествами (для отсортированных диапазонов)
Операции слияния (для отсортированных диапазонов)
Операции с кучей
Операции минимума/максимума
(C++11)
(C++17)
Операции лексикографического сравнения
Операции перестановок


Политики выполнения (C++17)
(только для пояснения*)(C++26)

Численные операции
(C++11)
(C++17)
(C++17)    

Специализированные <memory> алгоритмы

Специализированные <random> алгоритмы
Библиотека C









 
Определён в заголовке <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 ExecutionPolicy,
          class ForwardIt1, class ForwardIt2, class UnaryOp >
ForwardIt2 transform( ExecutionPolicy&& policy,
                      ForwardIt1 first1, ForwardIt1 last1,
                      ForwardIt2 d_first, UnaryOp unary_op );
(2) (начиная с 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 начиная с 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) (начиная с C++17)

std::transform применяет заданную функцию к элементам указанного входного диапазона (диапазонов), и сохраняет результат в выходном диапазоне, начиная с d_first.

1) Унарная операция unary_op применяется к элементам [first1, last1).
Если unary_op делает итератор недействительным или изменяет элемент в любом из следующих диапазонов, поведение не определено:
  • [first1, last1].
  • Диапазон из std::distance(first1, last1) + 1 элементов, начиная с d_first.
3) Бинарная операция binary_op применяется к парам элементов из двух диапазонов: [first1, last1) и другого диапазона из std::distance(first1, last1) элементов, начиная с first2.
Если binary_op делает итератор недействительным или изменяет элемент в любом из следующих диапазонов, поведение не определено:
  • [first1, last1].
  • Диапазон из std::distance(first1, last1) + 1 элементов, начиная с first2.
  • Диапазон из std::distance(first1, last1) + 1 элементов, начиная с d_first.
2,4) То же, что и (1,3), но выполняется в соответствии с policy.
Эти перегрузки участвуют в разрешении перегрузки только если значение следующего выражения равно true:

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

(до C++20)

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

(начиная с C++20)

Параметры

first1, last1 - пара итераторов, определяющих исходный диапазон элементов для преобразования
first2 - начало второго диапазона элементов для преобразования, ( 3,4 ) только
d_first - начало целевого диапазона, может быть равен first1 или first2
policy - политика выполнения для использования
unary_op - унарный функциональный объект операции, который будет применён.

Сигнатура функции должна быть эквивалентна следующей:

Ret fun ( const Type & a ) ;

Сигнатура не обязана иметь const & .
Тип Type должен быть таким, чтобы объект типа InputIt мог быть разыменован и неявно преобразован в Type . Тип Ret должен быть таким, чтобы объект типа OutputIt мог быть разыменован и ему присвоено значение типа Ret . ​

binary_op - бинарный функциональный объект операции, который будет применён.

Сигнатура функции должна быть эквивалентна следующей:

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

Сигнатура не обязана иметь const & .
Типы Type1 и Type2 должны быть такими, чтобы объекты типов InputIt1 и InputIt2 могли быть разыменованы и неявно преобразованы в Type1 и Type2 соответственно. Тип Ret должен быть таким, чтобы объект типа OutputIt мог быть разыменован и ему присвоено значение типа Ret . ​

Требования к типам
-
InputIt, InputIt1, InputIt2 должны удовлетворять требованиям LegacyInputIterator .
-
OutputIt должен удовлетворять требованиям LegacyOutputIterator .
-
ForwardIt1, ForwardIt2, ForwardIt3 должны удовлетворять требованиям LegacyForwardIterator .

Возвращаемое значение

Выходной итератор на элемент, следующий за последним преобразованным элементом.

Сложность

Дано N как std:: distance ( first1, last1 ) :

1,2) Ровно N применений unary_op .
3,4) Ровно N применений binary_op .

Исключения

Перегрузки с параметром шаблона с именем ExecutionPolicy сообщают об ошибках следующим образом:

  • Если выполнение функции, вызванной как часть алгоритма, выбрасывает исключение и ExecutionPolicy является одним из стандартных политик , std::terminate вызывается. Для любой другой ExecutionPolicy поведение определяется реализацией.
  • Если алгоритму не удается выделить память, std::bad_alloc выбрасывается.

Возможная реализация

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;
}
**Примечание:** Весь код C++ внутри тегов `
` и `` оставлен без изменений, как и требовалось. HTML-теги и атрибуты также сохранены в оригинальном виде.

Примечания

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);
}
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 (см. примечания выше)
    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)
{
    // Преобразование чисел в удвоенные значения
    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++.

DR Applied to Behavior as published Correct behavior
LWG 242 C++98 unary_op и binary_op не могли иметь побочных эффектов они не могут изменять задействованные диапазоны

См. также

применяет унарныйфункциональный объектк элементам издиапазона
(шаблон функции&алгоритмический функциональный объект)
применяет функцию к диапазону элементов
(алгоритмический функциональный объект)