Skip to main content

std::ranges::replace() algorithm

// (1)
constexpr I
replace( I first, S last, const T1& old_value, const T2& new_value,
Proj proj = {} );

// (2)
constexpr ranges::borrowed_iterator_t<R>
replace( R&& r, const T1& old_value, const T2& new_value, Proj proj = {} );

The type of arguments are generic and have the following constraints:

  • I - std::permutable
  • S - std::sentinel_for<I>
  • R - std::ranges::input_range
  • T1 - (none)
  • T2 - (none)
  • Proj - (none)

The Proj template argument has a default type of std::identity for all overloads.

Additionally, each overload has the following constraints:

  • (1):
    indirectly_writable<I, const T2&>
    && indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T1*>
  • (2):
    indirectly_writable<ranges::iterator_t<R>, const T2&>
    && indirect_binary_predicate<ranges::equal_to, projected<ranges::iterator_t<R>, Proj>, const T1*>

(The std:: namespace was ommitted here for readability)

  • (1) Replaces all elements that are equal to old_value with new_value, using std::invoke(proj, *i) == old_value to compare.

  • (2) Same as (1), but uses r as the source range, as if using ranges::begin(r) as first and ranges::end(r) as last.

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.

old_value

The value to search for and replace.

new_value

The value to use as a replacement.

proj

Projection to apply to the elements.

Return value​

An iterator equal to last.

Complexity​

Exactly ranges::distance(first, last) applications of the projection proj.

Exceptions​

(none)

Possible implementation​

replace(1)
struct replace_fn
{
template<std::input_iterator I, std::sentinel_for<I> S, class T1, class T2,
class Proj = std::identity>
requires std::indirectly_writable<I, const T2&> && std::indirect_binary_predicate<
ranges::equal_to, std::projected<I, Proj>, const T1*>
constexpr I
operator()(I first, S last, const T1& old_value, const T2& new_value,
Proj proj = {}) const
{
for (; first != last; ++first)
if (old_value == std::invoke(proj, *first))
*first = new_value;
return first;
}

template<ranges::input_range R, class T1, class T2, class Proj = std::identity>
requires std::indirectly_writable<ranges::iterator_t<R>, const T2&> &&
std::indirect_binary_predicate<ranges::equal_to,
std::projected<ranges::iterator_t<R>, Proj>, const T1*>
constexpr ranges::borrowed_iterator_t<R>
operator()(R&& r, const T1& old_value, const T2& new_value, Proj proj = {}) const
{
return (*this)(ranges::begin(r), ranges::end(r), old_value,
new_value, std::move(proj));
}
};

inline constexpr replace_fn replace {};

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​

Main.cpp

#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);
}
Output
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
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.

std::ranges::replace() algorithm

// (1)
constexpr I
replace( I first, S last, const T1& old_value, const T2& new_value,
Proj proj = {} );

// (2)
constexpr ranges::borrowed_iterator_t<R>
replace( R&& r, const T1& old_value, const T2& new_value, Proj proj = {} );

The type of arguments are generic and have the following constraints:

  • I - std::permutable
  • S - std::sentinel_for<I>
  • R - std::ranges::input_range
  • T1 - (none)
  • T2 - (none)
  • Proj - (none)

The Proj template argument has a default type of std::identity for all overloads.

Additionally, each overload has the following constraints:

  • (1):
    indirectly_writable<I, const T2&>
    && indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T1*>
  • (2):
    indirectly_writable<ranges::iterator_t<R>, const T2&>
    && indirect_binary_predicate<ranges::equal_to, projected<ranges::iterator_t<R>, Proj>, const T1*>

(The std:: namespace was ommitted here for readability)

  • (1) Replaces all elements that are equal to old_value with new_value, using std::invoke(proj, *i) == old_value to compare.

  • (2) Same as (1), but uses r as the source range, as if using ranges::begin(r) as first and ranges::end(r) as last.

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.

old_value

The value to search for and replace.

new_value

The value to use as a replacement.

proj

Projection to apply to the elements.

Return value​

An iterator equal to last.

Complexity​

Exactly ranges::distance(first, last) applications of the projection proj.

Exceptions​

(none)

Possible implementation​

replace(1)
struct replace_fn
{
template<std::input_iterator I, std::sentinel_for<I> S, class T1, class T2,
class Proj = std::identity>
requires std::indirectly_writable<I, const T2&> && std::indirect_binary_predicate<
ranges::equal_to, std::projected<I, Proj>, const T1*>
constexpr I
operator()(I first, S last, const T1& old_value, const T2& new_value,
Proj proj = {}) const
{
for (; first != last; ++first)
if (old_value == std::invoke(proj, *first))
*first = new_value;
return first;
}

template<ranges::input_range R, class T1, class T2, class Proj = std::identity>
requires std::indirectly_writable<ranges::iterator_t<R>, const T2&> &&
std::indirect_binary_predicate<ranges::equal_to,
std::projected<ranges::iterator_t<R>, Proj>, const T1*>
constexpr ranges::borrowed_iterator_t<R>
operator()(R&& r, const T1& old_value, const T2& new_value, Proj proj = {}) const
{
return (*this)(ranges::begin(r), ranges::end(r), old_value,
new_value, std::move(proj));
}
};

inline constexpr replace_fn replace {};

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​

Main.cpp

#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);
}
Output
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
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.