std::replace_copy, std::replace_copy_if

Header: <algorithm>

Copies the elements from the range [first,last) to another range beginning at d_first, while replacing all elements satisfying specific criteria with new_value.

# Declarations

template< class InputIt, class OutputIt, class T >
OutputIt replace_copy( InputIt first, InputIt last, OutputIt d_first,
const T& old_value, const T& new_value );

(constexpr since C++20)

template< class ExecutionPolicy,
class ForwardIt1, class ForwardIt2, class T >
ForwardIt2 replace_copy
( ExecutionPolicy&& policy,
ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first,
const T& old_value, const T& new_value );

(since C++17)

template< class InputIt, class OutputIt, class UnaryPred, class T >
OutputIt replace_copy_if
( InputIt first, InputIt last, OutputIt d_first,
UnaryPred p, const T& new_value );

(constexpr since C++20) (until C++26)

template< class InputIt, class OutputIt, class UnaryPred,
class T = typename std::iterator_traits
<OutputIt>::value_type >
constexpr OutputIt replace_copy_if
( InputIt first, InputIt last, OutputIt d_first,
UnaryPred p, const T& new_value );

(since C++26)

template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2,
class UnaryPred, class T >
ForwardIt2 replace_copy_if
( ExecutionPolicy&& policy,
ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first,
UnaryPred p, const T& new_value );

(since C++17) (until C++26)

template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2,
class UnaryPred, class T = typename std::iterator_traits
<ForwardIt2>::value_type >
ForwardIt2 replace_copy_if
( ExecutionPolicy&& policy,
ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first,
UnaryPred p, const T& new_value );

(since C++26)

# Parameters

# Return value

Iterator to the element past the last element copied.

# Notes

Feature-test macro Value Std Feature __cpp_lib_algorithm_default_value_type 202403 (C++26) List-initialization for algorithms (3,4)

# Example

#include <algorithm>
#include <complex>
#include <iostream>
#include <vector>
 
void println(const auto& seq)
{
    for (const auto& e : seq)
        std::cout << e << ' ';
    std::cout << '\n';
}
 
int main()
{
    std::vector<short> src{3, 1, 4, 1, 5, 9, 2, 6, 5};
    println(src);
    std::vector<int> dst(src.size());
    std::replace_copy_if(src.cbegin(), src.cend(),
                         dst.begin(),
                         [](short n){ return n > 5; }, 0);
    println(dst);
 
    std::vector<std::complex<double>> src2{{1, 3}, {2, 4}, {3, 5}},
                                      dst2(src2.size());
    println(src2);
    #ifdef __cpp_lib_algorithm_default_value_type
        std::replace_copy_if(src2.cbegin(), src2.cend(), dst2.begin(),
            [](std::complex<double> z){ return std::abs(z) < 5; },
            {4, 2}); // Possible, since the T is deduced.
    #else
        std::replace_copy_if(src2.cbegin(), src2.cend(), dst2.begin(),
            [](std::complex<double> z){ return std::abs(z) < 5; },
            std::complex<double>{4, 2});
    #endif
    println(dst2);
}

# Defect reports

DRApplied toBehavior as publishedCorrect behavior
LWG 283C++98T was required to be CopyAssignable (and EqualityComparable forreplace_copy), but the value type of InputIt is not always Tremoved the requirement
LWG 337C++98replace_copy_if only required InputIt tomeet the requirements of LegacyIterator[1]corrected toLegacyInputIterator

# See also