std::copy, std::copy_if
| Definido en el encabezado <algorithm>
|
||
template< class InputIt, class OutputIt >
OutputIt copy( InputIt first, InputIt last,
OutputIt d_first );
|
(1) | (constexpr desde C++20) |
template< class ExecutionPolicy,
class ForwardIt1, class ForwardIt2 >
ForwardIt2 copy( ExecutionPolicy&& policy,
ForwardIt1 first, ForwardIt1 last,
ForwardIt2 d_first );
|
(2) | (desde C++17) |
template< class InputIt, class OutputIt, class UnaryPred >
OutputIt copy_if( InputIt first, InputIt last,
OutputIt d_first, UnaryPred pred );
|
(3) | (desde C++11) (constexpr desde C++20) |
template< class ExecutionPolicy,
class ForwardIt1, class ForwardIt2, class UnaryPred >
ForwardIt2 copy_if( ExecutionPolicy&& policy,
ForwardIt1 first, ForwardIt1 last,
ForwardIt2 d_first, UnaryPred pred );
|
(4) | (desde C++17) |
Copia los elementos en el rango, definido por [first, last), a otro rango que comienza en d_first (rango de destino de la copia).
[first, last) comenzando desde first y avanzando hacia last.d_first está en [first, last), el comportamiento no está definido. En este caso, se puede usar std::copy_backward en su lugar.policy.true:
|
|
(hasta C++20) |
|
|
(desde C++20) |
[first, last) y el rango de destino de la copia se superponen, el comportamiento no está definido.pred devuelve true. Este algoritmo de copia es estable: el orden relativo de los elementos copiados se conserva.[first, last) y el rango de destino de la copia se superponen, el comportamiento no está definido.policy.true:
|
|
(hasta C++20) |
|
|
(desde C++20) |
Parámetros
| first, last | - | el par de iteradores que definen el rango fuente de elementos a copiar |
| d_first | - | el inicio del rango de destino |
| policy | - | la política de ejecución a utilizar |
| pred | - | predicado unario que devuelve true para los elementos requeridos. La expresión |
| Requisitos de tipo | ||
-InputIt debe cumplir los requisitos de LegacyInputIterator.
| ||
-OutputIt debe cumplir los requisitos de LegacyOutputIterator.
| ||
-ForwardIt1, ForwardIt2 debe cumplir los requisitos de LegacyForwardIterator.
| ||
-UnaryPred debe cumplir los requisitos de Predicate.
| ||
Valor de retorno
Iterador de salida al elemento en el rango de destino, uno más allá del último elemento copiado.
Complejidad
Dado N como std::distance(first, last):
pred, y como máximo N asignaciones.Para las sobrecargas con un ExecutionPolicy, puede haber un costo de rendimiento si el tipo de valor de ForwardIt1 no es MoveConstructible.
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 una de las políticas estándar, se llama a std::terminate. Para cualquier otroExecutionPolicy, el comportamiento está definido por la implementación. - Si el algoritmo falla al asignar memoria, se lanza std::bad_alloc.
Posible implementación
| copy (1) |
|---|
template<class InputIt, class OutputIt>
OutputIt copy(InputIt first, InputIt last,
OutputIt d_first)
{
for (; first != last; (void)++first, (void)++d_first)
*d_first = *first;
return d_first;
}
|
| copy_if (3) |
template<class InputIt, class OutputIt, class UnaryPred>
OutputIt copy_if(InputIt first, InputIt last,
OutputIt d_first, UnaryPred pred)
{
for (; first != last; ++first)
if (pred(*first))
{
*d_first = *first;
++d_first;
}
return d_first;
}
|
Notas
En la práctica, las implementaciones de std::copy evitan asignaciones múltiples y utilizan funciones de copia masiva como std::memmove si el tipo de valor es TriviallyCopyable y los tipos de iterador satisfacen LegacyContiguousIterator.
Al copiar rangos superpuestos, std::copy es apropiado al copiar hacia la izquierda (el inicio del rango de destino está fuera del rango fuente) mientras que std::copy_backward es apropiado al copiar hacia la derecha (el final del rango de destino está fuera del rango fuente).
Ejemplo
El siguiente código utiliza std::copy tanto para copiar el contenido de un std::vector a otro como para mostrar el std::vector resultante.
#include <algorithm>
#include <iostream>
#include <iterator>
#include <numeric>
#include <vector>
int main()
{
std::vector<int> from_vector(10);
std::iota(from_vector.begin(), from_vector.end(), 0);
std::vector<int> to_vector;
std::copy(from_vector.begin(), from_vector.end(), std::back_inserter(to_vector));
// or, alternatively,
// std::vector<int> to_vector(from_vector.size());
// std::copy(from_vector.begin(), from_vector.end(), to_vector.begin());
// either way is equivalent to
// std::vector<int> to_vector = from_vector;
std::cout << "to_vector contains: ";
std::copy(to_vector.begin(), to_vector.end(),
std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';
std::cout << "odd numbers in to_vector are: ";
std::copy_if(to_vector.begin(), to_vector.end(),
std::ostream_iterator<int>(std::cout, " "),
[](int x) { return x % 2 != 0; });
std::cout << '\n';
std::cout << "to_vector contains these multiples of 3: ";
to_vector.clear();
std::copy_if(from_vector.begin(), from_vector.end(),
std::back_inserter(to_vector),
[](int x) { return x % 3 == 0; });
for (const int x : to_vector)
std::cout << x << ' ';
std::cout << '\n';
}
Posible salida:
to_vector contains: 0 1 2 3 4 5 6 7 8 9
odd numbers in to_vector are: 1 3 5 7 9
to_vector contains these multiples of 3: 0 3 6 9
Informes de defectos
Los siguientes informes de defectos que cambian el comportamiento se aplicaron retroactivamente a los estándares C++ previamente publicados.
| DR | Aplicado a | Comportamiento como se publicó | Comportamiento correcto |
|---|---|---|---|
| LWG 2039 | C++11 | el valor de retorno de std::copy_if no estaba especificado
|
especificado |
| LWG 2044 | C++11 | la estabilidad de std::copy_if no estaba definida
|
definida |
Véase también
| copia un rango de elementos en orden inverso (plantilla de función & objeto de función de algoritmo) | |
(C++20) |
|
| crea una copia de un rango que está invertido (plantilla de función & objeto de función de algoritmo) | |
(C++20) |
|
(C++11) |
copia un número de elementos a una nueva ubicación (plantilla de función & objeto de función de algoritmo) |
(C++20) |
|
| asigna por copia el valor dado a cada elemento en un rango (plantilla de función & objeto de función de algoritmo) | |
(C++20) |
|
| copia un rango de elementos omitiendo aquellos que satisfacen criterios específicos (plantilla de función & objeto de función de algoritmo) | |
(C++20)(C++20) |
|
(C++20)(C++20) |
copia un rango de elementos a una nueva ubicación (objeto de función de algoritmo) |