std::replace
The standard library provides std::replace to replace elements within a container such as std::vector, std::list, or std::string. This generic algorithm iterates through the specified range and substitutes any element matching the old value with a new value.
The following example demonstrates replacing all occurrences of a value in a vector:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> data = {5, 10, 15, 10, 20, 10, 25};
const int target = 10;
const int replacement = 100;
std::replace(data.begin(), data.end(), target, replacement);
for (int val : data) {
std::cout << val << " ";
}
std::cout << std::endl;
return 0;
}
The output:
5 100 15 100 20 100 25
All instances of 10 have been replaced with 100.
The function signature:
template< class ForwardIt, class T >
ForwardIt replace( ForwardIt first, ForwardIt last, const T& old_value, const T& new_value );
firstandlastdefine the range to operate on via iterators.old_valuespecifies the value to search for.new_valuespecifies the replacement value.
The function returns an iterator pointing to the position just past the last element of the modified range.
When replacement must be based on a condition rather than an exact match, use std::replace_if with a predicate that returns a boolean.
std::replace_if
std::replace_if replaces elements in a range that satisfy a specified condition. The algorithm takes a range (defined by begin and end iterators), a unary predicate, and a replacement value. Elements for which the predicate returns true get replaced.
The example below replaces every even number in a vector with -1:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> data = {3, 6, 9, 12, 15, 18, 21, 24};
std::replace_if(data.begin(), data.end(),
[](int n) { return n % 2 == 0; }, -1);
for (int val : data) {
std::cout << val << " ";
}
std::cout << std::endl;
return 0;
}
The lambda [] captures the predicate: it evaluates true for even numbers (divisible by 2). Every element for which this condition holds gets replaced with -1.
The function signature:
template< class ForwardIt, class UnaryPredicate, class T >
ForwardIt replace_if( ForwardIt first, ForwardIt last, UnaryPredicate p, const T& new_value );
firstandlastare iterators marking the operation range.pis a unary predicate (function or function object) testing whether an element should be replaced.new_valueis the value to substitute for matching elements.
The return value points to the position following the last replaced element.
std::replace_copy
std::replace_copy copies elements from a source range to a destination range while replacing elements that meet a condition. The original container remains unchanged.
This algorithm accepts source range iterators, a destination range iterator, a predicate, and a replacement value. Elements satisfying the predicate are replaced during the copy operation.
The following example copies elements from one vector to another, substituting all values greater than 50 with 0:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> source = {20, 45, 60, 80, 35, 95, 10};
std::vector<int> dest(source.size());
auto end_iter = std::replace_copy(
source.begin(), source.end(),
dest.begin(),
[](int n) { return n > 50; },
0
);
dest.resize(end_iter - dest.begin());
for (int val : dest) {
std::cout << val << " ";
}
std::cout << std::endl;
return 0;
}
The predicate [] returns true when an element exceeds 50. Those elements become 0 in the destination vector, while other elements copy unchanged.
The function signature:
template< class InputIt, class OutputIt, class UnaryPredicate, class T >
OutputIt replace_copy( InputIt first1, InputIt last1, OutputIt d_first, UnaryPredicate p, const T& new_value );
first1andlast1mark the source range boundaries.d_firstis the starting iterator for the destination range where transformed elements are written.pis the unary predicate determining which elements get replaced.new_valueis the replacement value for matching elements.
The returned iterator indicates the position after the last copied element in the destination range.
std::replace_copy_if
std::replace_copy_if duplicates elements to a destination range while conditionally replacing specific elements. Unlike std::replace_if, this algorithm preserves the original data by writing results to a separate container.
The algorithm takes source range iterators, a destination iterator, a predicate, and a replacement value. For each source element, if the predicate evaluates to true, the replacement value gets written to the destination; otherwise, the original element copies over.
The example below demonstrates copying with selective replacement of negative values:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> source = {-5, 3, -8, 12, -1, 7, -20};
std::vector<int> dest(source.size());
auto end_iter = std::replace_copy_if(
source.begin(), source.end(),
dest.begin(),
[](int n) { return n < 0; },
0
);
dest.resize(end_iter - dest.begin());
for (int val : dest) {
std::cout << val << " ";
}
std::cout << std::endl;
return 0;
}
The predicate [] identifies negative numbers. Negative values become 0 in the destination, while non-negative values appear unchanged.
The function signature:
template< class InputIt, class OutputIt, class UnaryPredicate, class T >
OutputIt replace_copy_if( InputIt first1, InputIt last1, OutputIt d_first, UnaryPredicate p, const T& new_value );
first1andlast1define the input range boundaries.d_firstspecifies where output begins in the destination container.pevaluates each element to determine replacement eligibility.new_valuesubstitutes elements matching the predicate condition.
The returned iterator points past the final written element, enabling proper container resizing if needed.