Espacios de nombres
Variantes
Acciones

std::copy, std::copy_if

De cppreference.com
< cpp‎ | algorithm
 
 
Biblioteca de algoritmos
Políticas de ejecución (C++17)
Operaciones de secuencia no modificantes
(C++11)(C++11)(C++11)
(C++17)
Operaciones de secuencia modificantes
copycopy_if
(C++11)
(C++11)
(C++11)

Operaciones en almacenamiento no inicializado
Operaciones de partición
Operaciones de ordenación
(C++11)
Operaciones de búsqueda binaria
Operaciones de conjuntos (en rangos ordenados)
Operaciones de pila
(C++11)
Operaciones mínimo/máximo
(C++11)
(C++17)
Permutaciones
Operaciones numéricas
Bibliotecas C
 
Definido en el archivo de encabezado <algorithm>
(1)
template< class InputIt, class OutputIt >
OutputIt copy( InputIt first, InputIt last, OutputIt d_first );
(hasta C++20)
template< class InputIt, class OutputIt >
constexpr OutputIt copy( InputIt first, InputIt last, OutputIt d_first );
(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)
(3)
template< class InputIt, class OutputIt, class UnaryPredicate >

OutputIt copy_if( InputIt first, InputIt last,
                  OutputIt d_first,

                  UnaryPredicate pred );
(desde C++11)
(hasta C++20)
template< class InputIt, class OutputIt, class UnaryPredicate >

constexpr OutputIt copy_if( InputIt first, InputIt last,
                            OutputIt d_first,

                            UnaryPredicate pred );
(desde C++20)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class UnaryPredicate >

ForwardIt2 copy_if( ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last,
                  ForwardIt2 d_first,

                  UnaryPredicate pred );
(4) (desde C++17)

Copia los elementos en el rango definido por [first, last), a otro rango que inicia en d_first.

1) Copia todos los elementos en el rango [first, last) iniciando desde first y procediendo hasta last - 1. El comportamiento está indefinido si d_first se encuentra dentro del rango [first, last). En este caso, std::copy_backward puede usarse en su lugar.
3) Solamente copia los elementos para los que el predicado pred devuelve true. El orden relativo de los elementos que se copian se conserva. El comportamiento está indefinido si el rango fuente y el rango destino se superponen.
2,4) Igual que (1,3), pero ejecutado de acuerdo a la política de ejecución policy. Estas sobrecargas no participan en la resolución de sobrecarga a menos que std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> (hasta C++20) std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> (desde C++20) sea verdadera.

Contenido

[editar] Parámetros

first, last - El rango de elementos a copiar
d_first - El inicio del rango destino.
policy - La política de ejecución a usar. Véase política de ejecución para más detalles.
pred - Predicado unario que devuelve ​true para los elementos requeridos.

La signatura de la función predicado debe ser equivalente a:

 bool pred(const Type &a);

La forma no necesita tener const &, pero la función no debe modificar el objeto que se ha pasado.
El tipo Type debe ser tal que un objeto del tipo InputIt puede ser desreferenciado y entonces convertido implícitamente a Type. ​

Requerimientos de tipo
-
InputIt debe satisfacer los requerimientos de LegacyInputIterator.
-
OutputIt debe satisfacer los requerimientos de LegacyOutputIterator.
-
ForwardIt1, ForwardIt2 debe satisfacer los requerimientos de LegacyForwardIterator.
-
UnaryPredicate debe satisfacer los requerimientos de Predicate.

[editar] Valor de retorno

El iterador de salida al elemento en el rango destino, uno más allá del último elemento copiado.

[editar] Complejidad

1-2) Exactamente (last - first) asignaciones.
3-4) Exactamente (last - first) aplicaciones del predicado, entre 0 y (last - first) asignaciones (una asignación para cada elemento para el que el predicado es igual a true, dependiente del predicado y los datos de entrada).

Para las sobrecargas con una política de ejecución, ExecutionPolicy, podría haber un costo de rendimiento si el tipo del valor de ForwardIt1 no es MoveConstructible.

[editar] Excepciones

Las sobrecargas con un parámetro de plantilla llamado ExecutionPolicy (política de ejecución) reportan errores tales que:

  • Si la ejecución de una función invocada como parte del algoritmo lanza una excepción y la política de ejecución es una de las tres políticas estándar, se llama a std::terminate. Para cualquier otra política de ejecución, el comportamiento está definido por la implementación.
  • Si el algoritmo falla al asignar memoria, se lanza std::bad_alloc.

[editar] Notas

En la práctica, las implementaciones de std::copy evitan asignaciones múltiples y utilizan funciones de copia en masa tales como std::memmove si el tipo del valor es TriviallyCopyable y los tipos iterador satisfacen a LegacyContiguousIterator.

Al copiar rasgos que se superponen, std::copy es apropiado al copiar a la izquierda (el inicio del rango destino se encuentra fuera del rango fuente), mientras que std::copy_backward es apropiado al copiar a la derecha (el final del rango destino se encuentra fuera del rango fuente).

[editar] Posible implementación

Primera versión
template<class InputIt, class OutputIt>
OutputIt copy(InputIt first, InputIt last, 
              OutputIt d_first)
{
    while (first != last) {
        *d_first++ = *first++;
    }
    return d_first;
}
Segunda versión
template<class InputIt, class OutputIt, class UnaryPredicate>
OutputIt copy_if(InputIt first, InputIt last, 
                 OutputIt d_first, UnaryPredicate pred)
{
    while (first != last) {
        if (pred(*first))
            *d_first++ = *first;
        first++;
    }
    return d_first;
}

[editar] Ejemplo

El siguiente código utiliza copy para copiar tanto el contenido de un vector a otro como para mostrar el vector resultante:

#include <algorithm>
#include <iostream>
#include <vector>
#include <iterator>
#include <numeric>
 
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));
// o de manera alterna,
//  std::vector<int> to_vector(from_vector.size());
//  std::copy(from_vector.begin(), from_vector.end(), to_vector.begin());
// cualquier manera es equivalente a
//  std::vector<int> to_vector = from_vector;
 
    std::cout << "to_vector contiene: ";
 
    std::copy(to_vector.begin(), to_vector.end(),
              std::ostream_iterator<int>(std::cout, " "));
    std::cout << '\n';
 
	std::cout << "los nones en to_vector son: ";
 
    std::copy_if(to_vector.begin(), to_vector.end(),
                 std::ostream_iterator<int>(std::cout, " "),
                 [](int x) { return (x % 2) == 1; });
    std::cout << '\n';
}

Salida:

to_vector contiene: 0 1 2 3 4 5 6 7 8 9
los nones en to_vector son: 1 3 5 7 9

[editar] Véase también

Copia un rango de elementos en orden inverso
(plantilla de función) [editar]
Crea una copia de un rango que está invertida
(plantilla de función) [editar]
(C++11)
Copia un número de elementos a una nueva ubicación
(plantilla de función) [editar]
Asigna un cierto valor a una serie de elementos
(plantilla de función) [editar]
Copia un rango de elementos omitiendo los que satisfacen un criterio específico
(plantilla de función) [editar]