Namensräume
Varianten
Aktionen

std::copy, std::copy_if

Von cppreference.com
< cpp‎ | algorithm
 
 
Algorithmenbibliothek
Beschränkte Algorithmen und Algorithmen für Bereiche (C++20)
Beschränkte Algorithmen, z.B. ranges::copy, ranges::sort, ...
Ausführungsrichtlinien (C++17)
Nicht-modifizierende Sequenzoperationen
Stapeloperationen
(C++17)
Suchoperationen
(C++11)                (C++11)(C++11)

Modifizierende Sequenzoperationen
Kopieroperationen
copycopy_if
(C++11)
(C++11)
(C++11)
Tauschoperationen
Transformationsoperationen
Generierungsoperationen
Entfernungsoperationen
Ordnungsändernde Operationen
(bis C++17)(C++11)
(C++20)(C++20)
Stichprobenoperationen
(C++17)

Sortier- und verwandte Operationen
Partitionierungsoperationen
Sortieroperationen
Binäre Suchoperationen
(auf partitionierten Bereichen)
Mengenoperationen (auf sortierten Bereichen)
Zusammenführungsoperationen (auf sortierten Bereichen)
Heapoperationen
Minimum/Maximum-Operationen
(C++11)
(C++17)
Lexikographische Vergleichsoperationen
Permutationsoperationen
C-Bibliothek
Numerische Operationen
Operationen auf uninitialisiertem Speicher
 
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, der durch [firstlast) definiert ist, in einen anderen Bereich, der bei d_first beginnt (Zielbereich der Kopie).

1) Kopiert alle Elemente im Bereich [firstlast), beginnend bei first und fortschreitend bis last.
Wenn d_first sich im Bereich [firstlast) befindet, ist das Verhalten undefiniert. In diesem Fall kann stattdessen std::copy_backward verwendet werden.
2) Kopiert die Elemente, wird aber gemäß policy ausgeführt.
Diese Überladung nimmt an der Überladungsauflösung teil, nur wenn alle folgenden Bedingungen erfüllt sind

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> ist true.

(bis C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> ist true.

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

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> ist true.

(bis C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> ist true.

(seit C++20)

Inhalt

[bearbeiten] Parameter

first, last - das Iteratorpaar, das den Quell-Bereich der zu kopierenden Elemente definiert
d_first - der Anfang des Zielbereichs
policy - die Ausführungsrichtlinie, die verwendet werden soll
pred - unäres Prädikat, das für die erforderlichen Elemente ​true zurückgibt.

Der Ausdruck pred(v) muss für jedes Argument v vom Typ (möglicherweise const) VT, wobei VT der Werttyp von InputIt ist, unabhängig von der Wertkategorie, in bool konvertierbar sein und darf v nicht modifizieren. Daher ist ein Parametertyp von VT& nicht zulässig, ebenso wenig wie VT, es sei denn, für VT ist eine Verschiebung äquivalent zu einer Kopie(seit C++11). ​

Typanforderungen
-
InputIt muss die Anforderungen von LegacyInputIterator erfüllen.
-
OutputIt muss die Anforderungen an LegacyOutputIterator erfüllen.
-
ForwardIt1, ForwardIt2 müssen die Anforderungen an LegacyForwardIterator erfüllen.
-
UnaryPred muss die Anforderungen von Predicate erfüllen.

[bearbeiten] Rückgabewert

Iterator auf das Element im Zielbereich, eins nach dem letzten kopierten Element.

[bearbeiten] Komplexität

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

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

Bei Überladungen mit einer ExecutionPolicy kann es zu Leistungseinbußen kommen, wenn der Werttyp von ForwardIt1 nicht MoveConstructible ist.

[bearbeiten] Ausnahmen

Die Überladungen mit einem Template-Parameter namens ExecutionPolicy berichten Fehler wie folgt

  • Wenn die Ausführung einer Funktion, die als Teil des Algorithmus aufgerufen wird, eine Ausnahme auslöst und ExecutionPolicy eine der Standardrichtlinien ist, wird std::terminate aufgerufen. Für jede andere ExecutionPolicy ist das Verhalten implementierungsabhängig.
  • Wenn dem Algorithmus der Speicher zur Neuzuweisung fehlt, wird std::bad_alloc ausgelöst.

[bearbeiten] 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;
}

[bearbeiten] Hinweise

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

Beim Kopieren sich überschneidender 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).

[bearbeiten] Beispiel

Der folgende Code verwendet std::copy sowohl zum Kopieren des Inhalts eines std::vector in ein anderes als auch zur Anzeige des resultierenden std::vector.

#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

[bearbeiten] Defect Reports

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

DR angewendet auf Verhalten wie veröffentlicht Korrigiertes Verhalten
LWG 2039 C++11 Der Rückgabewert von std::copy_if war nicht spezifiziert spezifiziert
LWG 2044 C++11 Die Stabilität von std::copy_if war nicht definiert defined

[bearbeiten] Siehe auch

Kopiert einen Elementbereich in umgekehrter Reihenfolge
(Funktionstempelat) [edit]
Erstellt eine Kopie eines Bereichs, der umgekehrt ist
(Funktionstemplate) [edit]
(C++11)
Kopiert eine Anzahl von Elementen an einen neuen Speicherort
(Funktionstempelat) [edit]
Weist jedem Element in einem Bereich den gegebenen Wert zu
(Funktionstempelat) [edit]
Kopiert einen Bereich von Elementen und lässt diejenigen aus, die bestimmte Kriterien erfüllen
(Funktionstemplate) [edit]
Kopiert einen Elementbereich an einen neuen Speicherort
(Algorithmus-Funktionsobjekt)[edit]