std::copy, std::copy_if
| Definiert in Header <algorithm> |
||
template< class InputIt, class OutputIt > OutputIt copy( InputIt first, InputIt last, |
(1) | (constexpr seit C++20) |
| template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 > |
(2) | (seit C++17) |
template< class InputIt, class OutputIt, class UnaryPred > OutputIt copy_if( InputIt first, InputIt last, |
(3) | (seit C++11) (constexpr seit C++20) |
| template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class UnaryPred > |
(4) | (seit C++17) |
Kopiert die Elemente im Bereich, der durch [first, last) definiert ist, in einen anderen Bereich, der bei d_first beginnt (Zielbereich der Kopie).
[first, last), beginnend bei first und fortschreitend bis last.[first, last) befindet, ist das Verhalten undefiniert. In diesem Fall kann stattdessen std::copy_backward verwendet werden.|
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) |
[first, last) und der Zielbereich der Kopie sich überschneiden, ist das Verhalten undefiniert.[first, last) und der Zielbereich der Kopie sich überschneiden, ist das Verhalten undefiniert.|
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 |
| 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).
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
ExecutionPolicyeine der Standardrichtlinien ist, wird std::terminate aufgerufen. Für jede andereExecutionPolicyist 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) | |
| Erstellt eine Kopie eines Bereichs, der umgekehrt ist (Funktionstemplate) | |
| (C++11) |
Kopiert eine Anzahl von Elementen an einen neuen Speicherort (Funktionstempelat) |
| Weist jedem Element in einem Bereich den gegebenen Wert zu (Funktionstempelat) | |
| Kopiert einen Bereich von Elementen und lässt diejenigen aus, die bestimmte Kriterien erfüllen (Funktionstemplate) | |
| (C++20)(C++20) |
Kopiert einen Elementbereich an einen neuen Speicherort (Algorithmus-Funktionsobjekt) |