Namespaces
Variants

std:: replace_copy, std:: replace_copy_if

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
replace_copy replace_copy_if

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
Definido en el encabezado <algorithm>
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 ) ;
(1) (constexpr desde 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 ) ;
(2) (desde C++17)
(3)
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 desde C++20)
(hasta 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 ) ;
(desde C++26)
(4)
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 ) ;
(desde C++17)
(hasta 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 ) ;
(desde C++26)

Copia los elementos del rango [ first , last ) a otro rango que comienza en d_first , mientras reemplaza todos los elementos que cumplen criterios específicos con new_value .

1) Reemplaza todos los elementos que son iguales a old_value (utilizando operator == ).
3) Reemplaza todos los elementos para los cuales el predicado p devuelve true .
2,4) Igual que (1,3) , pero ejecutado de acuerdo con la policy .
Estas sobrecargas participan en la resolución de sobrecarga solo si se cumplen todas las siguientes condiciones:

std:: is_execution_policy_v < std:: decay_t < ExecutionPolicy >> es true .

(hasta C++20)

std:: is_execution_policy_v < std:: remove_cvref_t < ExecutionPolicy >> es true .

(desde C++20)

Si alguno de los resultados de las expresiones * first y new_value no es writable a d_first , el programa está mal formado.

Si los rangos de origen y destino se superponen, el comportamiento es indefinido.

Contenidos

Parámetros

first, last - el par de iteradores que define el rango fuente de elementos a copiar
d_first - el inicio del rango destino
old_value - el valor de los elementos a reemplazar
policy - la política de ejecución a utilizar
p - predicado unario que devuelve ​ true si el valor del elemento debe ser reemplazado.

La expresión p ( v ) debe ser convertible a bool para cada argumento v de tipo (posiblemente const) VT , donde VT es el tipo de valor de InputIt , independientemente de la categoría de valor , y no debe modificar v . Por lo tanto, un tipo de parámetro VT & no está permitido , ni tampoco VT a menos que para VT un movimiento sea equivalente a una copia (since C++11) . ​

new_value - el valor a utilizar como reemplazo
Requisitos de tipo
-
InputIt debe cumplir con los requisitos de LegacyInputIterator .
-
OutputIt debe cumplir con los requisitos de LegacyOutputIterator .
-
ForwardIt1, ForwardIt2 debe cumplir con los requisitos de LegacyForwardIterator .

Valor de retorno

Iterador al elemento después del último elemento copiado.

Complejidad

Dado N como std:: distance ( first, last ) :

1,2) Exactamente N comparaciones utilizando operator == .
3,4) Exactamente N aplicaciones del predicado p .

Excepciones

Las sobrecargas con un parámetro de plantilla llamado ExecutionPolicy reportan errores de la siguiente manera:

  • Si la ejecución de una función invocada como parte del algoritmo lanza una excepción y ExecutionPolicy es uno de los standard policies , std::terminate es llamado. Para cualquier otro ExecutionPolicy , el comportamiento está definido por la implementación.
  • Si el algoritmo falla al asignar memoria, std::bad_alloc es lanzado.

Implementación posible

replace_copy (1)
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)
{
    for (; first != last; ++first)
        *d_first++ = (*first == old_value) ? new_value : *first;
    return d_first;
}
replace_copy_if (3)
template<class InputIt, class OutputIt, class UnaryPred,
         class T = typename std::iterator_traits<ForwardIt>::value_type>
OutputIt replace_copy_if(InputIt first, InputIt last, OutputIt d_first,
                         UnaryPred p, const T& new_value)
{
    for (; first != last; ++first)
        *d_first++ = p(*first) ? new_value : *first;
    return d_first;
}

Notas

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

Ejemplo

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

Salida:

3 1 4 1 5 9 2 6 5 
3 1 4 1 5 0 2 0 5 
(1,3) (2,4) (3,5) 
(4,2) (4,2) (3,5)

Informes de defectos

Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.

DR Aplicado a Comportamiento publicado Comportamiento correcto
LWG 283 C++98 T se requería que fuera CopyAssignable (y EqualityComparable para
replace_copy ), pero el tipo de valor de InputIt no siempre es T
se eliminó el requisito
LWG 337 C++98 replace_copy_if solo requería que InputIt
cumpliera con los requisitos de LegacyIterator [1]
corregido a
LegacyInputIterator
  1. El defecto real en el estándar de C++ es que el parámetro de plantilla InputIterator fue especificado incorrectamente como Iterator . Esto afecta los requisitos de tipo porque el estándar de C++ establece que para las plantillas de función en la biblioteca de algoritmos, los parámetros de tipo de plantilla cuyo nombre termina con Iterator implican los requisitos de tipo de las categorías de iterador correspondientes.

Véase también

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