Namespaces
Variants

std:: copy, std:: 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
copy copy_if
(C++11)
(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
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 copia).

1) Copia todos los elementos en el rango [ first , last ) comenzando desde first y procediendo hasta last .
Si d_first está en [ first , last ) , el comportamiento es indefinido. En este caso, std::copy_backward puede ser utilizado en su lugar.
2) Copia los elementos, pero ejecutado de acuerdo con la policy .
Esta sobrecarga participa 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 [ first , last ) y el rango de destino de la copia se superponen, el comportamiento es indefinido.
3) Solo copia los elementos para los cuales el predicado pred devuelve true . Este algoritmo de copia es estable: el orden relativo de los elementos que se copian se preserva.
Si [ first , last ) y el rango de destino de la copia se superponen, el comportamiento es indefinido.
4) Igual que (3) , pero ejecutado de acuerdo con policy .
Esta sobrecarga participa 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)

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
policy - la política de ejecución a utilizar
pred - predicado unario que devuelve ​ true para los elementos requeridos.

La expresión pred ( 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, no se permite un tipo de parámetro VT & , ni tampoco VT a menos que para VT un movimiento sea equivalente a una copia (since C++11) . ​

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 .
-
UnaryPred debe cumplir con los requisitos de Predicate .

Valor de retorno

Iterador de salida al elemento en el rango de destino, un elemento después del último elemento copiado.

Complejidad

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

1,2) Exactamente N asignaciones.
3,4) Exactamente N aplicaciones del predicado pred , y como máximo N asignaciones.

Para las sobrecargas con una 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 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

copiar (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;
}
copiar_si (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 iteradores 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';
}

Salida posible:

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 modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.

DR Se aplica a Comportamiento publicado 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)
crea una copia de un rango que está invertido
(plantilla de función)
(C++11)
copia un número de elementos a una nueva ubicación
(plantilla de función)
asigna por copia el valor dado a cada elemento en un rango
(plantilla de función)
copia un rango de elementos omitiendo aquellos que cumplen criterios específicos
(plantilla de función)
copia un rango de elementos a una nueva ubicación
(objeto función de algoritmo)