std::ranges::replace_copy, std::ranges::replace_copy_if, std::ranges::replace_copy_result, std::ranges::replace_copy_if_result
Определён в заголовочном файле <algorithm> | ||
|---|---|---|
| Сигнатура вызова | ||
template< std::input_iterator I, std::sentinel_for<I> S, class T1, class T2,
std::output_iterator<const T2&> O, class Proj = std::identity >
requires std::indirectly_copyable<I, O> &&
std::indirect_binary_predicate
<ranges::equal_to, std::projected<I, Proj>, const T1*>
constexpr ranges::replace_copy_result<I, O>
replace_copy( I first, S last, O d_first, const T1& old_value,
const T2& new_value, Proj proj = {} );
| (1) |
(начиная с C++20) (до C++26) |
template< std::input_iterator I, std::sentinel_for<I> S,
class O, class Proj = std::identity,
class T1 = std::projected_value_t<I, Proj>,
class T2 = std::iter_value_t<O> >
requires std::indirectly_copyable<I, O> &&
std::indirect_binary_predicate
<ranges::equal_to, std::projected<I, Proj>, const T1*> &&
std::output_iterator<O, const T2&>
constexpr ranges::replace_copy_result<I, O>
replace_copy( I first, S last, O d_first, const T1& old_value,
const T2& new_value, Proj proj = {} );
| (начиная с C++26) | |
template< ranges::input_range R, class T1, class T2,
std::output_iterator<const T2&> O, class Proj = std::identity >
requires std::indirectly_copyable<ranges::iterator_t<R>, O> &&
std::indirect_binary_predicate
<ranges::equal_to,
std::projected<ranges::iterator_t<R>, Proj>, const T1*>
constexpr ranges::replace_copy_result<ranges::borrowed_iterator_t<R>, O>
replace_copy( R&& r, O d_first, const T1& old_value,
const T2& new_value, Proj proj = {} );
| (2) |
(начиная с C++20) (до C++26) |
template< ranges::input_range R,
class O, class Proj = std::identity,
class T1 = std::projected_value_t<ranges::iterator_t<R>, Proj>,
class T2 = std::iter_value_t<O> >
requires std::indirectly_copyable<ranges::iterator_t<R>, O> &&
std::indirect_binary_predicate
<ranges::equal_to,
std::projected<ranges::iterator_t<R>, Proj>, const T1*> &&
std::output_iterator<O, const T2&>
constexpr ranges::replace_copy_result<ranges::borrowed_iterator_t<R>, O>
replace_copy( R&& r, O d_first, const T1& old_value,
const T2& new_value, Proj proj = {} );
| (начиная с C++26) | |
template< std::input_iterator I, std::sentinel_for<I> S,
class T, std::output_iterator<const T&> O,
class Proj = std::identity,
std::indirect_unary_predicate<std::projected<I, Proj>> Pred >
requires std::indirectly_copyable<I, O>
constexpr ranges::replace_copy_if_result<I, O>
replace_copy_if( I first, S last, O d_first, Pred pred,
const T& new_value, Proj proj = {} );
| (3) |
(начиная с C++20) (до C++26) |
template< std::input_iterator I, std::sentinel_for<I> S,
class O, class T = std::iter_value_t<O>
class Proj = std::identity,
std::indirect_unary_predicate<std::projected<I, Proj>> Pred >
requires std::indirectly_copyable<I, O> && std::output_iterator<O, const T&>
constexpr ranges::replace_copy_if_result<I, O>
replace_copy_if( I first, S last, O d_first, Pred pred,
const T& new_value, Proj proj = {} );
| (начиная с C++26) | |
template< ranges::input_range R,
class T, std::output_iterator<const T&> O,
class Proj = std::identity,
std::indirect_unary_predicate
<std::projected<ranges::iterator_t<R>, Proj>> Pred >
requires std::indirectly_copyable<ranges::iterator_t<R>, O>
constexpr ranges::replace_copy_if_result<ranges::borrowed_iterator_t<R>, O>
replace_copy_if( R&& r, O d_first, Pred pred,
const T& new_value, Proj proj = {} );
| (4) |
(начиная с C++20) (до C++26) |
template< ranges::input_range R,
class O, class T = std::iter_value_t<O>
class Proj = std::identity,
std::indirect_unary_predicate
<std::projected<ranges::iterator_t<R>, Proj>> Pred >
requires std::indirectly_copyable<ranges::iterator_t<R>, O> &&
std::output_iterator<O, const T&>
constexpr ranges::replace_copy_if_result<ranges::borrowed_iterator_t<R>, O>
replace_copy_if( R&& r, O d_first, Pred pred,
const T& new_value, Proj proj = {} );
| (начиная с C++26) | |
template< /*execution-policy*/ Ep,
std::random_access_iterator I, std::sized_sentinel_for<I> S,
std::random_access_iterator O, std::sized_sentinel_for<O> OutS,
class Proj = std::identity,
class T1 = std::projected_value_t<I, Proj>,
class T2 = std::iter_value_t<O> >
requires std::indirectly_copyable<I, O> &&
std::indirect_binary_predicate
<ranges::equal_to, std::projected<I, Proj>, const T1*> &&
std::indirectly_writable<O, const T2&>
ranges::replace_copy_result<I, O>
replace_copy( Ep&& policy, I first, S last,
O d_first, OutS d_last, const T1& old_value,
const T2& new_value, Proj proj = {} );
| (5) | (начиная с C++26) |
template< /*execution-policy*/ Ep,
/*sized-random-access-range*/ R,
/*sized-random-access-range*/ OutR,
class Proj = std::identity,
class T1 = std::projected_value_t<ranges::iterator_t<R>, Proj>,
class T2 = ranges::range_value_t<OutR> >
requires std::indirectly_copyable<ranges::iterator_t<R>,
ranges::iterator_t<OutR>> &&
std::indirect_binary_predicate
<ranges::equal_to,
std::projected<ranges::iterator_t<R>, Proj>, const T1*> &&
std::indirectly_writable<ranges::iterator_t<OutR>, const T2&>
ranges::replace_copy_result<ranges::borrowed_iterator_t<R>,
ranges::borrowed_iterator_t<OutR>>
replace_copy( Ep&& policy, R&& r, OutR&& d_r, const T1& old_value,
const T2& new_value, Proj proj = {} );
| (6) | (начиная с C++26) |
template< /*execution-policy*/ Ep,
std::random_access_iterator I, std::sized_sentinel_for<I> S,
std::random_access_iterator O, std::sized_sentinel_for<O> OutS,
class T = std::iter_value_t<O>, class Proj = std::identity,
std::indirect_unary_predicate<projected<I, Proj>> Pred >
requires std::indirectly_copyable<I, O> &&
std::indirectly_writable<O, const T&>
ranges::replace_copy_if_result<I, O>
replace_copy_if( Ep&& policy, I first, S last,
O d_first, OutS d_last, Pred pred,
const T& new_value, Proj proj = {} );
| (7) | (начиная с C++26) |
template< /*execution-policy*/ Ep,
/*sized-random-access-range*/ R,
/*sized-random-access-range*/ OutR,
class T = ranges::range_value_t<OutR>,
class Proj = std::identity,
std::indirect_unary_predicate
<std::projected<ranges::iterator_t<R>, Proj>> Pred >
requires std::indirectly_copyable<ranges::iterator_t<R>,
ranges::iterator_t<OutR>> &&
std::indirectly_writable<OutR, const T& >
ranges::replace_copy_if_result<ranges::borrowed_iterator_t<R>,
ranges::borrowed_iterator_t<OutR>>
replace_copy_if( Ep&& policy, R&& r, OutR&& d_r, Pred pred,
const T& new_value, Proj proj = {} );
| (8) | (начиная с C++26) |
| Вспомогательные типы | ||
template< class I, class O > using replace_copy_result = ranges::in_out_result<I, O>; | (9) | (начиная с C++20) |
template< class I, class O > using replace_copy_if_result = ranges::in_out_result<I, O>; | (10) | (начиная с C++20) |
Определение /*execution-policy*/ см. на этой странице; определение /*sized-random-access-range*/ см. на этой странице.
Копирует элементы (преобразованные с помощью proj) из исходного диапазона [first, last) или r в целевой диапазон, заменяя все элементы, удовлетворяющие заданным критериям, на new_value.
[d_first, ranges::next(d_first, count)), где count — это ranges::distance(first, last) или ranges::distance(r).replace_copy заменяет все элементы, равные old_value (с использованием operator==).replace_copy_if заменяет все элементы, для которых предикат pred возвращает true.policy, а целевой диапазон — это [d_first, d_last) или d_r. Если целевой диапазон исчерпан до достижения конца исходного диапазона, оставшиеся элементы исходного диапазона копироваться не будут.Если какой-либо из результатов выражений *first и new_value нельзя записать в d_first или ranges::begin(d_r), программа некорректна.
Если исходный и целевой диапазоны перекрываются, поведение не определено.
Функциональные сущности, описанные на этой странице, являются объектами-функциями алгоритмов (неформально называемыми niebloids), то есть:
- При вызове любой из них нельзя указывать явный список аргументов шаблона.
- Ни одна из них не видна для поиска с учётом аргументов.
- Когда любая из них находится с помощью обычного неквалифицированного поиска как имя слева от оператора вызова функции, поиск с учётом аргументов подавляется.
Параметры
| first, last | - | пара итераторов, задающих исходный диапазон |
| r | - | исходный диапазон |
| d_first | - | начало целевого диапазона |
| d_last | - | сторожевой объект целевого диапазона |
| d_r | - | целевой диапазон |
| old_value | - | значение элементов, которые нужно заменить |
| new_value | - | значение для замены |
| pred | - | предикат, применяемый к преобразованным элементам |
| proj | - | проекция, применяемая к элементам |
| policy | - | политика выполнения |
Возвращаемое значение
Объект типа ranges::replace_copy_result или ranges::replace_copy_if_result, в котором:
- Поле данных
inсодержит итератор, следующий за последним скопированным элементом исходного диапазона (независимо от того, выполнялась ли замена), либо итератор на начало исходного диапазона, если ни один элемент не скопирован. - Поле данных
outсодержит итератор, следующий за последним присвоенным элементом целевого диапазона, либо итератор на начало целевого диапазона, если ни одному элементу не присвоено значение.
Сложность
Пусть
- \(\scriptsize N_1\)N1 — это
ranges::distance(first, last)илиranges::distance(r), - \(\scriptsize N_2\)N2 — это
ranges::distance(d_first, d_last)илиranges::distance(d_r):
proj.pred и proj.proj.pred и proj.Примечания
| Макрос проверки поддержки функциональности | Значение | Стандарт | Функциональность |
|---|---|---|---|
__cpp_lib_algorithm_default_value_type | 202403 | (C++26) | инициализация списком для алгоритмов (1-4) |
Возможная реализация
| replace_copy |
|---|
struct replace_copy_fn
{
template<std::input_iterator I, std::sentinel_for<I> S,
class O, class Proj = std::identity,
class T1 = std::projected_value_t<I, Proj>,
class T2 = std::iter_value_t<O>>
requires std::indirectly_copyable<I, O> &&
std::indirect_binary_predicate
<ranges::equal_to, std::projected<I, Proj>, const T1*> &&
std::output_iterator<O, const T2&>
constexpr ranges::replace_copy_result<I, O>
operator()(I first, S last, O result, const T1& old_value,
const T2& new_value, Proj proj = {}) const
{
for (; first != last; ++first, ++result)
*result = (std::invoke(proj, *first) == old_value) ? new_value : *first;
return {std::move(first), std::move(result)};
}
template<ranges::input_range R, class O, class Proj = std::identity,
class T1 = std::projected_value_t<ranges::iterator_t<R>, Proj>,
class T2 = std::iter_value_t<O>>
requires std::indirectly_copyable<ranges::iterator_t<R>, O> &&
std::indirect_binary_predicate
<ranges::equal_to,
std::projected<ranges::iterator_t<R>, Proj>, const T1*>
constexpr ranges::replace_copy_result<ranges::borrowed_iterator_t<R>, O>
operator()(R&& r, O result, const T1& old_value,
const T2& new_value, Proj proj = {}) const
{
return (*this)(ranges::begin(r), ranges::end(r),
std::move(result), old_value, new_value, std::move(proj));
}
template<ranges::forward_range R, class O, class Proj = std::identity,
class T1 = std::projected_value_t<ranges::iterator_t<R>, Proj>,
class T2 = std::iter_value_t<O>>
requires std::indirectly_copyable<ranges::iterator_t<R>, O> &&
std::indirect_binary_predicate
<ranges::equal_to,
std::projected<ranges::iterator_t<R>, Proj>, const T1*>
constexpr ranges::replace_copy_result<ranges::borrowed_iterator_t<R>, O>
operator()(R&& r, O result, const T1& old_value,
const T2& new_value, Proj proj = {}) const
{
return (*this)(ranges::begin(r),
ranges::next(ranges::begin(r), ranges::end(r)),
std::move(result), old_value, new_value, std::move(proj));
}
};
inline constexpr replace_copy_fn replace_copy{};
|
| replace_copy_if |
struct replace_copy_if_fn
{
template<std::input_iterator I, std::sentinel_for<I> S,
class O, class T = std::iter_value_t<O>
class Proj = std::identity,
std::indirect_unary_predicate<std::projected<I, Proj>> Pred>
requires std::indirectly_copyable<I, O> && std::output_iterator<O, const T&>
constexpr ranges::replace_copy_if_result<I, O>
operator()(I first, S last, O result, Pred pred,
const T& new_value, Proj proj = {}) const
{
for (; first != last; ++first, ++result)
*result = std::invoke(pred, std::invoke(proj, *first)) ? new_value : *first;
return {std::move(first), std::move(result)};
}
template<ranges::input_range R, class O, class T = std::iter_value_t<O>
class Proj = std::identity,
std::indirect_unary_predicate
<std::projected<ranges::iterator_t<R>, Proj>> Pred>
requires std::indirectly_copyable<ranges::iterator_t<R>, O> &&
std::output_iterator<O, const T&>
constexpr ranges::replace_copy_if_result<ranges::borrowed_iterator_t<R>, O>
operator()(R&& r, O result, Pred pred,
const T& new_value, Proj proj = {}) const
{
return (*this)(ranges::begin(r), ranges::end(r),
std::move(result), std::move(pred), new_value, std::move(proj));
}
template<ranges::forward_range R, class O, class T = std::iter_value_t<O>
class Proj = std::identity,
std::indirect_unary_predicate
<std::projected<ranges::iterator_t<R>, Proj>> Pred>
requires std::indirectly_copyable<ranges::iterator_t<R>, O> &&
std::output_iterator<O, const T&>
constexpr ranges::replace_copy_if_result<ranges::borrowed_iterator_t<R>, O>
operator()(R&& r, O result, Pred pred,
const T& new_value, Proj proj = {}) const
{
return (*this)(ranges::begin(r),
ranges::next(ranges::begin(r), ranges::end(r)),
std::move(result), std::move(pred), new_value, std::move(proj));
}
};
inline constexpr replace_copy_if_fn replace_copy_if{};
|
Пример
#include <algorithm>
#include <array>
#include <complex>
#include <iostream>
#include <vector>
void println(const auto rem, const auto& v)
{
for (std::cout << rem << ": "; const auto& e : v)
std::cout << e << ' ';
std::cout << '\n';
}
int main()
{
std::vector<int> o;
std::array p{1, 6, 1, 6, 1, 6};
o.resize(p.size());
println("p", p);
std::ranges::replace_copy(p, o.begin(), 6, 9);
println("o", o);
std::array q{1, 2, 3, 6, 7, 8, 4, 5};
o.resize(q.size());
println("q", q);
std::ranges::replace_copy_if(q, o.begin(), [](int x) { return 5 < x; }, 5);
println("o", o);
std::vector<std::complex<short>> r{{1, 3}, {2, 2}, {4, 8}};
std::vector<std::complex<float>> s(r.size());
println("r", r);
#ifdef __cpp_lib_algorithm_default_value_type
std::ranges::replace_copy(r, s.begin(),
{1, 3}, // T1 gets deduced
{2.2, 4.8}); // T2 gets deduced
#else
std::ranges::replace_copy(r, s.begin(),
std::complex<short>{1, 3},
std::complex<float>{2.2, 4.8});
#endif
println("s", s);
std::vector<std::complex<double>> b{{1, 3}, {2, 2}, {4, 8}},
d(b.size());
println("b", b);
#ifdef __cpp_lib_algorithm_default_value_type
std::ranges::replace_copy_if(b, d.begin(),
[](std::complex<double> z){ return std::abs(z) < 5; },
{4, 2}); // Possible, since the T is deduced.
#else
std::ranges::replace_copy_if(b, d.begin(),
[](std::complex<double> z){ return std::abs(z) < 5; },
std::complex<double>{4, 2});
#endif
println("d", d);
}
Вывод:
p: 1 6 1 6 1 6 o: 1 9 1 9 1 9 q: 1 2 3 6 7 8 4 5 o: 1 2 3 5 5 5 4 5 r: (1,3) (2,2) (4,8) s: (2.2,4.8) (2,2) (4,8) b: (1,3) (2,2) (4,8) d: (4,2) (4,2) (4,8)
См. также
| копирует диапазон, заменяя элементы, удовлетворяющие заданным критериям, другим значением (шаблон функции) |
|
|
(C++20)(C++20) | заменяет все значения, удовлетворяющие заданным критериям, другим значением (объект-функция алгоритма) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/algorithm/ranges/replace_copy