std:: replace_copy, std:: replace_copy_if
|
Definido en el encabezado
<algorithm>
|
||
|
template
<
class
InputIt,
class
OutputIt,
class
T
>
OutputIt replace_copy
(
InputIt first, InputIt last, OutputIt d_first,
|
(1) | (constexpr desde C++20) |
|
template
<
class
ExecutionPolicy,
class
ForwardIt1,
class
ForwardIt2,
class
T
>
|
(2) | (desde C++17) |
| (3) | ||
|
template
<
class
InputIt,
class
OutputIt,
class
UnaryPred,
class
T
>
OutputIt replace_copy_if
|
(constexpr desde C++20)
(hasta C++26) |
|
|
template
<
class
InputIt,
class
OutputIt,
class
UnaryPred,
class
T
=
typename
std::
iterator_traits
|
(desde C++26) | |
| (4) | ||
|
template
<
class
ExecutionPolicy,
class
ForwardIt1,
class
ForwardIt2,
class
UnaryPred,
class
T
>
|
(desde C++17)
(hasta C++26) |
|
|
template
<
class
ExecutionPolicy,
class
ForwardIt1,
class
ForwardIt2,
class
UnaryPred,
class
T
=
typename
std::
iterator_traits
|
(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
.
|
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
|
| 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 ) :
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
ExecutionPolicyes uno de los standard policies , std::terminate es llamado. Para cualquier otroExecutionPolicy, 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 |
-
↑
El defecto real en el estándar de C++ es que el parámetro de plantilla
InputIteratorfue especificado incorrectamente comoIterator. 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 conIteratorimplican 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) |
|
|
(C++20)
(C++20)
|
copia un rango, reemplazando elementos que cumplen criterios específicos con otro valor
(objeto función de algoritmo) |