std::replace_copy, std::replace_copy_if
Определено в заголовочном файле <algorithm> | ||
|---|---|---|
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 );
| (1) | (constexpr с C++20) |
template< class InputIt, class OutputIt, class UnaryPred, class T >
OutputIt replace_copy_if
( InputIt first, InputIt last, OutputIt d_first,
UnaryPred p, const T& new_value );
| (2) |
(constexpr с C++20) (до C++26) |
template< class InputIt, class OutputIt, class UnaryPred,
class T = typename std::iterator_traits
<OutputIt>::value_type >
constexpr OutputIt replace_copy_if
( InputIt first, InputIt last, OutputIt d_first,
UnaryPred p, const T& new_value );
| (начиная с C++26) | |
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 );
| (3) | (начиная с C++17) |
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2,
class UnaryPred, class T >
ForwardIt2 replace_copy_if
( ExecutionPolicy&& policy,
ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first,
UnaryPred p, const T& new_value );
| (4) |
(начиная с C++17) (до C++26) |
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2,
class UnaryPred, class T = typename std::iterator_traits
<ForwardIt2>::value_type >
ForwardIt2 replace_copy_if
( ExecutionPolicy&& policy,
ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first,
UnaryPred p, const T& new_value );
| (начиная с C++26) |
Копирует элементы из исходного диапазона [first, last) в диапазон назначения d_first, заменяя все элементы, удовлетворяющие определенным критериям, на new_value.
replace_copy заменяет все элементы, равные old_value (с использованием operator==).replace_copy_if заменяет все элементы, для которых предикат p возвращает true.policy.true: |
| (до C++20) |
|
| (начиная с C++20) |
Если результат любого из выражений *first и new_value нельзя записать в d_first, программа некорректна.
Если исходный диапазон и диапазон назначения перекрываются, поведение не определено.
Параметры
| first, last | - | пара итераторов, определяющих исходный диапазон |
| d_first | - | начало диапазона назначения |
| old_value | - | значение элементов, которые нужно заменить |
| p | - | унарный предикат, возвращающий true, если значение элемента следует заменить. Выражение |
| new_value | - | значение, используемое для замены |
| policy | - | политика выполнения, которую следует использовать |
| Требования к типам | ||
-InputIt должен удовлетворять требованиям LegacyInputIterator. |
||
-OutputIt должен удовлетворять требованиям LegacyOutputIterator. |
||
-ForwardIt1, ForwardIt2 должен удовлетворять требованиям LegacyForwardIterator. |
||
Возвращаемое значение
Итератор, следующий за последним элементом диапазона назначения.
Сложность
Пусть \(\scriptsize N\)N — std::distance(first, last):
p.p.Исключения
3,4) Во время выполнения:- Если временные ресурсы памяти, необходимые для параллельного выполнения, недоступны, генерируется
std::bad_alloc. - Если при доступе к объектам через аргумент алгоритма возникает неперехваченное исключение, поведение определяется политикой выполнения (для стандартных политик вызывается
std::terminate).
Примечания
| Макрос проверки поддержки возможностей | Значение | Стандарт | Возможность |
|---|---|---|---|
__cpp_lib_algorithm_default_value_type | 202403 | (C++26) | Инициализация списком для алгоритмов (3,4) |
Возможная реализация
| 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 UnaryPred,
class T = typename std::iterator_traits<ForwardIt>::value_type>
OutputIt replace_copy_if(InputIt first, InputIt last, OutputIt d_first,
UnaryPred p, const T& new_value)
{
for (; first != last; ++first)
*d_first++ = p(*first) ? new_value : *first;
return d_first;
}
|
Пример
#include <algorithm>
#include <complex>
#include <iostream>
#include <vector>
void println(const auto& seq)
{
for (const auto& e : seq)
std::cout << e << ' ';
std::cout << '\n';
}
int main()
{
std::vector<short> src{3, 1, 4, 1, 5, 9, 2, 6, 5};
println(src);
std::vector<int> dst(src.size());
std::replace_copy_if(src.cbegin(), src.cend(),
dst.begin(),
[](short n){ return n > 5; }, 0);
println(dst);
std::vector<std::complex<double>> src2{{1, 3}, {2, 4}, {3, 5}},
dst2(src2.size());
println(src2);
#ifdef __cpp_lib_algorithm_default_value_type
std::replace_copy_if(src2.cbegin(), src2.cend(), dst2.begin(),
[](std::complex<double> z){ return std::abs(z) < 5; },
{4, 2}); // Possible, since the T is deduced.
#else
std::replace_copy_if(src2.cbegin(), src2.cend(), dst2.begin(),
[](std::complex<double> z){ return std::abs(z) < 5; },
std::complex<double>{4, 2});
#endif
println(dst2);
}
Вывод:
3 1 4 1 5 9 2 6 5 3 1 4 1 5 0 2 0 5 (1,3) (2,4) (3,5) (4,2) (4,2) (3,5)
Отчеты об ошибках
Следующие отчеты об ошибках, изменяющие поведение, были применены задним числом к ранее опубликованным стандартам 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) | копирует диапазон, заменяя элементы, соответствующие определенным критериям, другим значением (функциональный объект алгоритма) |
| заменяет все значения, соответствующие определенным критериям, другим значением (шаблон функции и функциональный объект алгоритма) |
|
|
(C++20)(C++20) | |
| удаляет элементы, соответствующие определенным критериям (шаблон функции и функциональный объект алгоритма) |
|
|
(C++20)(C++20) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/algorithm/replace_copy