Namespaces
Variants

std::copy, std::copy_if

Von de.cppreference.net
 
 
Algorithmus-Bibliothek
Eingeschränkte Algorithmen und Algorithmen auf Bereichen (C++20)
Eingeschränkte Algorithmen, z. B. ranges::copy, ranges::sort, ...
Nicht modifizierende Sequenzoperationen    
Stapeloperationen
(C++17)
Suchoperationen
Modifizierende Sequenzoperationen
Kopieroperationen
(C++11)
(C++11)
Tauschoperationen
Transformationsoperationen
Erzeugungsoperationen
Entfernungsoperationen
Reihenfolgeändernde Operationen
(bis C++17)(C++11)
(C++20)(C++20)
Stichprobenoperationen
(C++17)

Sortier- und verwandte Operationen
Partitionierungsoperationen
(C++11)    

Sortieroperationen
Binäre Suchoperationen
(auf partitionierten Bereichen)
Mengenoperationen (auf sortierten Bereichen)
Mischoperationen (auf sortierten Bereichen)
Heap-Operationen
Minimum/Maximum-Operationen
(C++11)
(C++17)
Lexikografische Vergleichsoperationen
Permutationsoperationen


 
Definiert in Header <algorithm>
template< class InputIt, class OutputIt >
OutputIt copy( InputIt first, InputIt last,
               OutputIt d_first );
(1) (constexpr seit C++20)
template< class ExecutionPolicy,
          class ForwardIt1, class ForwardIt2 >
ForwardIt2 copy( ExecutionPolicy&& policy,
                 ForwardIt1 first, ForwardIt1 last,
                 ForwardIt2 d_first );
(2) (seit C++17)
template< class InputIt, class OutputIt, class UnaryPred >
OutputIt copy_if( InputIt first, InputIt last,
                  OutputIt d_first, UnaryPred pred );
(3) (seit C++11)
(constexpr seit 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) (seit C++17)

Kopiert die Elemente im Bereich, definiert durch [first, last), in einen anderen Bereich, der bei d_first beginnt (Zielbereich der Kopie).

1) Kopiert alle Elemente im Bereich [first, last) beginnend bei first und fortschreitend zu last.
Wenn d_first in [first, last) liegt, ist das Verhalten undefiniert. In diesem Fall kann std::copy_backward stattdessen verwendet werden.
2) Kopiert die Elemente, aber ausgeführt gemäß policy.
Diese Überladung nimmt nur an der Überladungsauflösung teil, wenn der Wert des folgenden Ausdrucks true ist:

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>

(bis C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>

(seit C++20)
Wenn [first, last) und der Zielbereich der Kopie sich überschneiden, ist das Verhalten undefiniert.
3) Kopiert nur die Elemente, für die das Prädikat pred true zurückgibt. Dieser Kopieralgorithmus ist stabil: die relative Reihenfolge der kopierten Elemente bleibt erhalten.
Wenn [first, last) und der Zielbereich der Kopie sich überschneiden, ist das Verhalten undefiniert.
4) Dasselbe wie (3), aber ausgeführt gemäß policy.
Diese Überladung nimmt nur an der Überladungsauflösung teil, wenn der Wert des folgenden Ausdrucks true ist:

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>

(bis C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>

(seit C++20)

Parameter

first, last - das Paar von Iteratoren, das den Quellbereich der zu kopierenden Elemente definiert
d_first - der Anfang des Zielbereichs
policy - die zu verwendende Ausführungsrichtlinie
pred - unäres Prädikat, das ​true für die erforderlichen Elemente zurückgibt.

Der Ausdruck pred(v) muss in bool konvertierbar sein für jedes Argument v vom Typ (ggf. const) VT, wobei VT der Werttyp von InputIt ist, unabhängig von der Wertkategorie, und darf v nicht modifizieren. Daher ist ein Parametertyp von VT& nicht erlaubt, auch nicht VT außer wenn für VT eine Verschiebung gleich einer Kopie ist(seit C++11). ​

Typanforderungen
-
InputIt muss die Anforderungen von LegacyInputIterator erfüllen.
-
OutputIt muss die Anforderungen von LegacyOutputIterator erfüllen.
-
ForwardIt1, ForwardIt2 muss die Anforderungen von LegacyForwardIterator erfüllen.
-
UnaryPred muss die Anforderungen von Prädikat erfüllen.

Rückgabewert

Ausgabe-Iterator auf das Element im Zielbereich, das auf das zuletzt kopierte Element folgt.

Komplexität

Gegeben N als std::distance(first, last):

1,2) Genau N Zuweisungen.
3,4) Genau N Anwendungen des Prädikats pred und höchstens N Zuweisungen.

Für die Überladungen mit einem ExecutionPolicy kann es einen Leistungseinbuße geben, wenn der Werttyp von ForwardIt1 nicht MoveConstructible ist.

Ausnahmen

Die Überladungen mit einem Vorlagenparameter namens ExecutionPolicy melden Fehler wie folgt:

  • Wenn die Ausführung einer im Rahmen des Algorithmus aufgerufenen Funktion eine Ausnahme auslöst und ExecutionPolicy eine der Standardrichtlinien ist, wird std::terminate aufgerufen. Für jede andere ExecutionPolicy ist das Verhalten implementierungsdefiniert.
  • Wenn der Algorithmus keinen Speicher zuweisen kann, wird std::bad_alloc ausgelöst.

Mögliche Implementierung

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;
}

Hinweise

In der Praxis vermeiden Implementierungen von std::copy mehrere Zuweisungen und verwenden Massenkopierfunktionen wie std::memmove, wenn der Werttyp TriviallyCopyable ist und die Iteratortypen LegacyContiguousIterator erfüllen.

Beim Kopieren überlappender Bereiche ist std::copy geeignet, wenn nach links kopiert wird (Anfang des Zielbereichs liegt außerhalb des Quellbereichs), während std::copy_backward geeignet ist, wenn nach rechts kopiert wird (Ende des Zielbereichs liegt außerhalb des Quellbereichs).

Beispiel

Der folgende Code verwendet std::copy, um sowohl den Inhalt eines std::vector in einen anderen zu kopieren als auch den resultierenden std::vector anzuzeigen.

#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';
}

Mögliche Ausgabe:

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

Fehlerberichte

Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR Angewendet auf Verhalten wie veröffentlicht Richtiges Verhalten
LWG 2039 C++11 der Rückgabewert von std::copy_if wurde nicht angegeben angegeben
LWG 2044 C++11 die Stabilität von std::copy_if war nicht definiert definiert

Siehe auch

kopiert einen Bereich von Elementen in umgekehrter Reihenfolge
(Funktionsschablone & Algorithmusfunktionsobjekt)
erstellt eine Kopie eines umgekehrten Bereichs
(Funktionsschablone & Algorithmusfunktionsobjekt)
(C++11)
kopiert eine Anzahl von Elementen an eine neue Position
(Funktionsschablone & Algorithmusfunktionsobjekt)
kopiert den gegebenen Wert per Zuweisung in jedes Element eines Bereichs
(Funktionsschablone & Algorithmusfunktionsobjekt)
kopiert einen Bereich von Elementen und lässt dabei diejenigen aus, die bestimmte Kriterien erfüllen
(Funktionsschablone & Algorithmusfunktionsobjekt)
kopiert einen Bereich von Elementen an eine neue Position
(Algorithmusfunktionsobjekt)