Пространства имён
Варианты
Действия

std::transform

Материал из cppreference.com
< cpp‎ | algorithm
 
 
Алгоритмы
Функции
Немодифицирующие линейные операции
Модифицирующие линейные операции
Разделение
Сортировка (на отсортированных промежутках)
Бинарный поиск (на отсортированных промежутках)
Множества (на отсортированных промежутках)
Куча
Минимум/максимум
Числовые операции
Библиотека C
 
Определено в заголовочном файле <algorithm>
template< class InputIt, class OutputIt, class UnaryOperation >

OutputIt transform( InputIt first1, InputIt last1, OutputIt d_first,

                    UnaryOperation unary_op );
(1)
template< class InputIt1, class InputIt2, class OutputIt, class BinaryOperation >

OutputIt transform( InputIt1 first1, InputIt1 last1, InputIt2 first2,

                    OutputIt d_first, BinaryOperation binary_op );
(2)

Применяет заданную функцию к одному диапазону и сохраняет результат в другой диапазон, начинающийся с d_first.

В первом варианте унарная операция unary_op применяется к диапазону [first1, last1). Во втором варианте бинарная операция binary_op применяется к элементам из двух диапазонов: [first1, last1) и начинающемуся с first2.

Содержание

[править] Параметры

first1, last1 - первый диапазон элементов для изменения
first2 - начало второго диапазона элементов для изменения
d_first - начало целевого диапазона, может совпадать с first1 или first2
unary_op - unary operation function object that will be applied.

The signature of the function should be equivalent to the following:

 Ret fun(const Type &a);

The signature does not need to have const &.
Тип  Type должен быть таков, что объект типа InputIt может быть разыменован и затем неявно преобразован в  Type. Тип  Ret должен быть таков, что объект типа OutputIt может быть разыменован, а результату разыменования присвоено значение типа  Ret. ​

binary_op - binary operation function object that will be applied.

The signature of the function should be equivalent to the following:

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

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

Требования к типам
-
InputIt должен соответствовать требованиям InputIterator.
-
InputIt1 должен соответствовать требованиям InputIterator.
-
InputIt2 должен соответствовать требованиям InputIterator.
-
OutputIt должен соответствовать требованиям OutputIterator.

[править] Возвращаемое значение

Output-итератор на элемент, следующий за последним изменённым.

[править] Сложность

1) Ровно std::distance(first1, last1) применений unary_op.

2) Ровно std::distance(first1, last1) применений binary_op.

[править] Требования

unary_op и binary_op не имеют побочных эффектов. (до C++11)

unary_op и binary_op не делают некорректными никакие итераторы (включая конечные) и не изменяют никакие элементы участвующих диапазонов. (начиная с C++11)

Целью этих требований является возможность параллельных или неупорядоченных реализаций функции std::transform. Чтобы применить функцию к последовательности по порядку, следует использовать std::for_each.

[править] Возможная реализация

Первый вариант
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;
}
Второй вариант
template<class InputIt1, class InputIt2,
         class OutputIt, class BinaryOperation>
OutputIt transform(InputIt first1, InputIt last1, InputIt first2,
                   OutputIt d_first, BinaryOperation binary_op)
{
    while (first1 != last1) {
        *d_first++ = binary_op(*first1++, *first2++);
    }
    return d_first;
}

[править] Пример

Следующий код использует std::transform для приведения строки в верхний регистр при помощи функции std::toupper:

#include <string>
#include <cctype>
#include <algorithm>
#include <iostream>
 
int main()
{
    std::string s("hello");
    std::transform(s.begin(), s.end(), s.begin(), (int (*)(int))std::toupper);
    std::cout << s;
}

Вывод:

HELLO

[править] См. также

Применяет функцию к диапазону элементов
(шаблон функции) [edit]