std::replace, std::replace_if
Определён в заголовочном файле <algorithm> | ||
|---|---|---|
template< class ForwardIt, class T >
void replace( ForwardIt first, ForwardIt last,
const T& old_value, const T& new_value );
| (1) |
(constexpr начиная с C++20) (до C++26) |
template< class ForwardIt,
class T = typename std::iterator_traits<ForwardIt>::value_type >
constexpr void replace( ForwardIt first, ForwardIt last,
const T& old_value, const T& new_value );
| (начиная с C++26) | |
template< class ForwardIt, class UnaryPred, class T >
void replace_if( ForwardIt first, ForwardIt last,
UnaryPred p, const T& new_value );
| (2) |
(constexpr начиная с C++20) (до C++26) |
template< class ForwardIt, class UnaryPred,
class T = typename std::iterator_traits
<ForwardIt>::value_type> >
constexpr void replace_if( ForwardIt first, ForwardIt last,
UnaryPred p, const T& new_value );
| (начиная с C++26) | |
template< class ExecutionPolicy, class ForwardIt, class T >
void replace( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last,
const T& old_value, const T& new_value );
| (3) |
(начиная с C++17) (до C++26) |
template< class ExecutionPolicy, class ForwardIt,
class T = typename std::iterator_traits<ForwardIt>::value_type >
void replace( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last,
const T& old_value, const T& new_value );
| (начиная с C++26) | |
template< class ExecutionPolicy,
class ForwardIt, class UnaryPred, class T >
void replace_if( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last,
UnaryPred p, const T& new_value );
| (4) |
(начиная с C++17) (до C++26) |
template< class ExecutionPolicy, class ForwardIt, class UnaryPred,
class T = typename std::iterator_traits<ForwardIt>::value_type> >
void replace_if( ExecutionPolicy&& policy,
ForwardIt first, ForwardIt last,
UnaryPred p, const T& new_value );
| (начиная с C++26) |
Заменяет элементы в целевом диапазоне [first, last) на new_value, если они соответствуют определённым критериям.
replace заменяет все элементы, равные old_value (с использованием operator==).replace_if заменяет все элементы, для которых предикат p возвращает true.policy.true: |
| (до C++20) |
|
| (начиная с C++20) |
Если *first = new_value недопустимо(до C++20)new_value недоступно для записи в first(начиная с C++20), программа некорректна.
Параметры
| first, last | - | пара итераторов, определяющая целевой диапазон |
| old_value | - | значение элементов, подлежащих замене |
| p | - | унарный предикат, возвращающий true, если значение элемента должно быть заменено. Выражение |
| new_value | - | значение, используемое для замены |
| policy | - | политика выполнения, которую следует использовать |
| Требования к типам | ||
-ForwardIt должен соответствовать требованиям LegacyForwardIterator. |
||
-UnaryPred должен соответствовать требованиям Predicate. |
||
Сложность
Пусть \(\scriptsize N\)N — std::distance(first, last):
p.p.Исключения
3,4) В процессе выполнения:- Если временные ресурсы памяти, необходимые для распараллеливания, недоступны, выбрасывается
std::bad_alloc. - Если при доступе к объектам через аргумент алгоритма возникает неперехваченное исключение, поведение определяется политикой выполнения (для стандартных политик вызывается
std::terminate).
Примечания
Поскольку алгоритм принимает old_value и new_value по ссылке, его поведение может быть неожиданным, если любой из них является ссылкой на элемент целевого диапазона.
| Макрос проверки поддержки возможностей | Значение | Стандарт | Возможность |
|---|---|---|---|
__cpp_lib_algorithm_default_value_type | 202403 | (C++26) | Инициализация списком для алгоритмов (1-4) |
Возможная реализация
| replace |
|---|
template<class ForwardIt,
class T = typename std::iterator_traits<ForwardIt>::value_type>
void replace(ForwardIt first, ForwardIt last,
const T& old_value, const T& new_value)
{
for (; first != last; ++first)
if (*first == old_value)
*first = new_value;
}
|
| replace_if |
template<class ForwardIt, class UnaryPred,
class T = typename std::iterator_traits<ForwardIt>::value_type>
void replace_if(ForwardIt first, ForwardIt last,
UnaryPred p, const T& new_value)
{
for (; first != last; ++first)
if (p(*first))
*first = new_value;
}
|
Пример
#include <algorithm>
#include <array>
#include <complex>
#include <functional>
#include <iostream>
void println(const auto& seq)
{
for (const auto& e : seq)
std::cout << e << ' ';
std::cout << '\n';
}
int main()
{
std::array<int, 10> s{5, 7, 4, 2, 8, 6, 1, 9, 0, 3};
// Replace all occurrences of 8 with 88.
std::replace(s.begin(), s.end(), 8, 88);
println(s);
// Replace all values less than 5 with 55.
std::replace_if(s.begin(), s.end(),
std::bind(std::less<int>{}, std::placeholders::_1, 5), 55);
println(s);
std::array<std::complex<double>, 2> nums{{{1, 3}, {1, 3}}};
#ifdef __cpp_lib_algorithm_default_value_type
std::replace(nums.begin(), nums.end(), {1, 3}, {4, 2});
#else
std::replace(nums.begin(), nums.end(), std::complex<double>{1, 3},
std::complex<double>{4, 2});
#endif
println(nums);
}
Вывод:
5 7 4 2 88 6 1 9 0 3 5 7 55 55 88 6 55 9 55 55 (4,2), (4,2)
Отчёты об ошибках
Следующие отчёты об ошибках, изменяющие поведение, были применены задним числом к ранее опубликованным стандартам C++.
| Отчёт об ошибке | Применяется к | Опубликованное поведение | Правильное поведение |
|---|---|---|---|
| LWG 283 | C++98 |
T должно было удовлетворять требованиям CopyAssignable (и EqualityComparableдля replace), но тип значения ForwardIt невсегда является T, а T не всегда доступно для записи в ForwardIt | вместо этого требовалось, чтобы *first = new_valueбыло корректным |
См. также
|
(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