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. Если исходный и целевой диапазоны перекрываются, поведение неопределено.
old_value (используя operator==).p возвращает true. policy. Эти перегрузки не участвуют в разрешении перегрузки, если |
| (до C++20) |
|
| (с C++20) |
Параметры
| first, last | - | диапазон копируемых элементов |
| d_first | - | начало целевого диапазона |
| old_value | - | значение элементов для замены |
| policy | - | политика выполнения. Подробности см. в политике выполнения. |
| p | - | унарный предикат, который возвращает true , если значение элемента должно быть заменено. Выражение |
| new_value | - | значение для использования в качестве замены |
| Требования к типу | ||
-InputIt должно соответствовать требованиям LegacyInputIterator. |
||
-OutputIt должно соответствовать требованиям LegacyOutputIterator. |
||
-ForwardIt1, ForwardIt2 должно соответствовать требованиям LegacyForwardIterator. |
||
-Результаты выражений *first и new_value должны быть доступны для записи в d_first. |
||
Возвращаемое значение
Итератор на элемент после последнего скопированного элемента.
Сложность
При условии N как std::distance(first, last):
N сравнений с old_value с использованием operator==.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 |
- Фактической ошибкой в стандарте C++ является неправильное указание параметра шаблона
InputIteratorкакIterator. Это влияет на требования к типу, поскольку стандарт C++ гласит, что для функций-шаблонов в библиотеке алгоритмов параметры типа шаблона, имена которых оканчиваются наIterator, подразумевают требования к типу соответствующих категорий итераторов.
См. также
| заменяет все значения, удовлетворяющие определённым критериям, другим значением (функция-шаблон) |
|
| удаляет элементы, удовлетворяющие определенным критериям (функция-шаблон) |
|
|
(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