Namespaces
Variants

std::ranges:: replace_copy, std::ranges:: replace_copy_if, std::ranges:: replace_copy_result, std::ranges:: replace_copy_if_result

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
Constrained algorithms
All names in this menu belong to namespace std::ranges
Non-modifying sequence operations
Modifying sequence operations
Partitioning operations
Sorting operations
Binary search operations (on sorted ranges)
Set operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Permutation operations
Fold operations
Operations on uninitialized storage
Return types
Definido en el encabezado <algorithm>
Firma de llamada
(1)
template < std:: input_iterator I, std:: sentinel_for < I > S, class T1, class T2,

std:: output_iterator < const T2 & > O, class Proj = std:: identity >
requiere std:: indirectly_copyable < I, O > &&
std:: indirect_binary_predicate
< ranges:: equal_to , std :: projected < I, Proj > , const T1 * >
constexpr replace_copy_result < I, O >
replace_copy ( I first, S last, O result, const T1 & old_value,

const T2 & new_value, Proj proj = { } ) ;
(desde C++20)
(hasta 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 > >
requiere 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 replace_copy_result < I, O >
replace_copy ( I first, S last, O result, const T1 & old_value,

const T2 & new_value, Proj proj = { } ) ;
(desde C++26)
(2)
template < ranges:: input_range R, class T1, class T2,

std:: output_iterator < const T2 & > O, class Proj = std:: identity >
requiere 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 replace_copy_result < ranges:: borrowed_iterator_t < R > , O >
replace_copy ( R && r, O resultado, const T1 & valor_antiguo,

const T2 & valor_nuevo, Proj proyeccion = { } ) ;
(desde C++20)
(hasta 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 replace_copy_result < ranges:: borrowed_iterator_t < R > , O >
replace_copy ( R && r, O result, const T1 & old_value,

const T2 & new_value, Proj proj = { } ) ;
(desde C++26)
(3)
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 replace_copy_if_result < I, O >
replace_copy_if ( I first, S last, O result, Pred pred,

const T & new_value, Proj proj = { } ) ;
(desde C++20)
(hasta 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 replace_copy_if_result < I, O >
replace_copy_if ( I first, S last, O result, Pred pred,

const T & new_value, Proj proj = { } ) ;
(desde C++26)
(4)
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 replace_copy_if_result < ranges:: borrowed_iterator_t < R > , O >
replace_copy_if ( R && r, O result, Pred pred,

const T & new_value, Proj proj = { } ) ;
(desde C++20)
(hasta 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 replace_copy_if_result < ranges:: borrowed_iterator_t < R > , O >
replace_copy_if ( R && r, O result, Pred pred,

const T & new_value, Proj proj = { } ) ;
(desde C++26)
Tipos auxiliares
template < class I, class O >
using replace_copy_result = ranges:: in_out_result < I, O > ;
(5) (desde C++20)
template < class I, class O >
using replace_copy_if_result = ranges:: in_out_result < I, O > ;
(6) (desde C++20)

Copia los elementos del rango fuente [ first , last ) al rango destino que comienza en result , reemplazando todos los elementos que cumplen criterios específicos con new_value . El comportamiento es indefinido si los rangos fuente y destino se superponen.

1) Reemplaza todos los elementos que son iguales a old_value , usando std:: invoke ( proj, * ( first + ( i - result ) ) ) == old_value para comparar.
3) Reemplaza todos los elementos para los cuales el predicado pred evalúa a true , donde la expresión de evaluación es std:: invoke ( pred, std:: invoke ( proj, * ( first + ( i - result ) ) ) ) .
2,4) Igual que (1,3) , pero utiliza r como el rango fuente, como si usara ranges:: begin ( r ) como first , y ranges:: end ( r ) como last .

Las entidades similares a funciones descritas en esta página son algorithm function objects (conocidas informalmente como niebloids ), es decir:

Contenidos

Parámetros

first, last - el par iterador-centinela que define el rango de elementos a copiar
r - el rango de elementos a copiar
result - el inicio del rango destino
old_value - el valor de los elementos a reemplazar
new_value - el valor a utilizar como reemplazo
pred - predicado a aplicar a los elementos proyectados
proj - proyección a aplicar a los elementos

Valor de retorno

{ last, result + N } , donde

1,3) N = ranges:: distance ( first, last ) ;
2,4) N = ranges:: distance ( r ) .

Complejidad

Exactamente N aplicaciones del predicado correspondiente comp y cualquier proyección proj .

Implementación posible

replace_copy (1,2)
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));
    }
};
inline constexpr replace_copy_fn replace_copy {};
replace_copy_if (3,4)
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));
    }
};
inline constexpr replace_copy_if_fn replace_copy_if {};

Notas

Macro de prueba de características Valor Std Característica
__cpp_lib_algorithm_default_value_type 202403 (C++26) Inicialización de lista para algoritmos ( 1-4 )

Ejemplo

#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 se deduce
                                  {2.2, 4.8}); // T2 se deduce
    #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}); // Posible, ya que el T se deduce.
    #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);
}

Salida:

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)

Véase también

reemplaza todos los valores que cumplen criterios específicos con otro valor
(objeto función de algoritmo)
copia un rango, reemplazando elementos que cumplen criterios específicos con otro valor
(plantilla de función)