std::ranges::replace_if() algorithm
- since C++20
- Simplified
- Detailed
// (1)
constexpr I
replace_if( I first, S last, Pred pred, const T& new_value, Proj proj = {} );
// (2)
constexpr ranges::borrowed_iterator_t<R>
replace_if( R&& r, Pred pred, const T& new_value, Proj proj = {} );
The type of arguments are generic and have the following constraints:
I-std::input_iteratorS-std::sentinel_for<I>R-std::ranges::input_rangeT- (none)Proj- (none)Pred:- (1) -
std::indirect_unary_predicate<std::projected<I, Proj>> - (2) -
std::indirect_unary_predicate< std::projected<ranges::iterator_t<R>, Proj>>
The Proj template argument has a default type of std::identity for all overloads.
Additionally, each overload has the following constraints:
- (1) -
std::indirectly_writable<I, const T&> - (2) -
std::indirectly_writable<ranges::iterator_t<R>, const T&>
(The std:: namespace was ommitted here for readability)
// (1)
template<
std::input_iterator I,
std::sentinel_for<I> S,
class T,
class Proj = std::identity,
std::indirect_unary_predicate<std::projected<I, Proj>> Pred
>
requires std::indirectly_writable<I, const T&>
constexpr I
replace_if( I first, S last, Pred pred, const T& new_value, Proj proj = {} );
// (2)
template<
ranges::input_range R,
class T, class Proj = std::identity,
std::indirect_unary_predicate< std::projected<ranges::iterator_t<R>, Proj>> Pred
>
requires std::indirectly_writable<ranges::iterator_t<R>, const T&>
constexpr ranges::borrowed_iterator_t<R>
replace_if( R&& r, Pred pred, const T& new_value, Proj proj = {} );
-
(1) Replaces all elements for which the predicate
predevaluates totrue, where evaluating expression isstd::invoke(pred, std::invoke(proj, *i)). -
(2) Same as (1), but uses
ras the source range, as if usingranges::begin(r)asfirstandranges::end(r)aslast.
Removing is done by shifting (by means of move assignment) the elements in the range in such a way that the elements that are not to be replaced appear in the beginning of the range.
Relative order of the elements that remain is preserved and the physical size of the container is unchanged.
Iterators pointing to an element between the new logical end and the physical end of the range are still dereferenceable, but the elements themselves have unspecified values (as per MoveAssignable post-condition). (since C++11)
The function-like entities described on this page are niebloids.
Parameters
first last | The range of elements to process. |
r | The range of elements to process. |
new_value | The value to use as a replacement. |
proj | Projection to apply to the elements. |
pred | Unary predicate which returns |
Return value
An iterator equal to last.
Complexity
Exactly ranges::distance(first, last) applications of the corresponding predicate pred and any projection proj.
Exceptions
(none)
Possible implementation
replace_if(1)
Notes
Because the algorithm takes old_value and new_value by reference, it may have unexpected behavior if either is a reference to an element of the range [first; last).
Examples
#include <algorithm>
#include <array>
#include <iostream>
int main()
{
auto print = [](const auto& v)
{
for (const auto& e : v)
std::cout << e << ' ';
std::cout << '\n';
};
std::array p {1, 6, 1, 6, 1, 6};
print(p);
std::ranges::replace(p, 6, 9);
print(p);
std::array q {1, 2, 3, 6, 7, 8, 4, 5};
print(q);
std::ranges::replace_if(q, [](int x) { return 5 < x; }, 5);
print(q);
}
1 6 1 6 1 6
1 9 1 9 1 9
1 2 3 6 7 8 4 5
1 2 3 5 5 5 4 5
Hover to see the original license.