Spec-Zone.ru › C++

std::replace_copy, std::replace_copy_if

Определено в заголовке <algorithm>
(1)
template< class InputIt, class OutputIt, class T >
OutputIt replace_copy( InputIt first, InputIt last, OutputIt d_first,
                       const T& old_value, const T& new_value );
(до C++20)
template< class InputIt, class OutputIt, class T >
constexpr OutputIt replace_copy( InputIt first, InputIt last, OutputIt d_first,
                                 const T& old_value, const T& new_value );
(с C++20)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class T >
ForwardIt2 replace_copy( ExecutionPolicy&& policy,
                         ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first,
                         const T& old_value, const T& new_value );
(2) (с C++17)
(3)
template< class InputIt, class OutputIt, class UnaryPredicate, class T >
OutputIt replace_copy_if( InputIt first, InputIt last, OutputIt d_first,
                          UnaryPredicate p, const T& new_value );
(до C++20)
template< class InputIt, class OutputIt, class UnaryPredicate, class T >
constexpr OutputIt replace_copy_if( InputIt first, InputIt last,
                                    OutputIt d_first,
                                    UnaryPredicate p, const T& new_value );
(с C++20)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2,
          class UnaryPredicate, class T >
ForwardIt2 replace_copy_if( ExecutionPolicy&& policy,
                            ForwardIt1 first, ForwardIt1 last,
                            ForwardIt2 d_first,
                            UnaryPredicate p, const T& new_value );
(4) (с C++17)

Копирует элементы из диапазона [first, last) в другой диапазон, начиная с d_first, заменяя все элементы, удовлетворяющие определенным критериям, на new_value. Если исходный и целевой диапазоны перекрываются, поведение неопределено.

1) Заменяет все элементы, равные old_value (используя operator==).
3) Заменяет все элементы, для которых предикат p возвращает true.
2,4) То же, что (1,3), но выполняется в соответствии с policy. Эти перегрузки не участвуют в разрешении перегрузки, если

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> является true.

(до C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> является true.

(с C++20)

Параметры

first, last - диапазон копируемых элементов
d_first - начало целевого диапазона
old_value - значение элементов для замены
policy - политика выполнения. Подробности см. в политике выполнения.
p - унарный предикат, который возвращает ​true , если значение элемента должно быть заменено.

Выражение p(v) должно быть приводимо к bool для каждого аргумента v типа (возможно, const) VT, где VT - тип значения InputIt, независимо от категории значения, и не должен изменять v. Таким образом, тип параметра VT& запрещен, так же, как и VT , если для VT перемещение эквивалентно копированию(с C++11). ​

new_value - значение для использования в качестве замены
Требования к типу
-InputIt должно соответствовать требованиям LegacyInputIterator.
-OutputIt должно соответствовать требованиям LegacyOutputIterator.
-ForwardIt1, ForwardIt2 должно соответствовать требованиям LegacyForwardIterator.
-Результаты выражений *first и new_value должны быть доступны для записи в d_first.

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

Итератор на элемент после последнего скопированного элемента.

Сложность

При условии N как std::distance(first, last):

1,2) ровно N сравнений с old_value с использованием operator==.
3,4) ровно N применений предиката p.

Исключения

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

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

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

replace_copy
template<class InputIt, class OutputIt, class T>
OutputIt replace_copy(InputIt first, InputIt last, OutputIt d_first,
                      const T& old_value, const T& new_value)
{
    for (; first != last; ++first)
        *d_first++ = (*first == old_value) ? new_value : *first;
    return d_first;
}
replace_copy_if
template<class InputIt, class OutputIt, class UnaryPredicate, class T>
OutputIt replace_copy_if(InputIt first, InputIt last, OutputIt d_first,
                         UnaryPredicate p, const T& new_value)
{
    for (; first != last; ++first)
        *d_first++ = p(*first) ? new_value : *first;
    return d_first;
}

Пример

В следующем примере копируется и выводится вектор, заменяя на лету все значения, превышающие 5 , на 99.

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
 
int main()
{
    std::vector<int> v{5, 7, 4, 2, 8, 6, 1, 9, 0, 3};
    std::replace_copy_if(v.begin(), v.end(),
                         std::ostream_iterator<int>(std::cout, " "),
                         [](int n){ return n > 5; }, 99);
    std::cout << '\n';
}

Вывод:

5 99 4 2 99 99 1 99 0 3

Отчеты об ошибках

Следующие отчеты об ошибках, изменяющие поведение, были применены ретроактивно к ранее опубликованным стандартам C++.

DR Применён к Опубликованное поведение Корректное поведение
LWG 283 C++98 T должно было быть CopyAssignable (и EqualityComparable для
replace_copy), но тип значения InputIt не всегда T
требование удалено
LWG 337 C++98 replace_copy_if требовало только InputIt соответствовать требованиям LegacyIterator[1] исправлено на
LegacyInputIterator
  1. Фактической ошибкой в стандарте C++ является неправильное указание параметра шаблона InputIterator как Iterator. Это влияет на требования к типу, поскольку стандарт C++ гласит, что для функций-шаблонов в библиотеке алгоритмов параметры типа шаблона, имена которых оканчиваются на Iterator, подразумевают требования к типу соответствующих категорий итераторов.

См. также

replacereplace_if
заменяет все значения, удовлетворяющие определённым критериям, другим значением
(функция-шаблон)
removeremove_if
удаляет элементы, удовлетворяющие определенным критериям
(функция-шаблон)
ranges::replace_copyranges::replace_copy_if
(C++20)(C++20)
копирует диапазон, заменяя элементы, удовлетворяющие определенным критериям, другим значением
(niebloid)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/algorithm/replace_copy

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API