std::copy, std::copy_if
| 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).
[first, last) beginnend bei first und fortschreitend zu last.d_first in [first, last) liegt, ist das Verhalten undefiniert. In diesem Fall kann std::copy_backward stattdessen verwendet werden.policy.true ist:
|
|
(bis C++20) |
|
|
(seit C++20) |
[first, last) und der Zielbereich der Kopie sich überschneiden, ist das Verhalten undefiniert.pred true zurückgibt. Dieser Kopieralgorithmus ist stabil: die relative Reihenfolge der kopierten Elemente bleibt erhalten.[first, last) und der Zielbereich der Kopie sich überschneiden, ist das Verhalten undefiniert.policy.true ist:
|
|
(bis C++20) |
|
|
(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 |
| 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):
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
ExecutionPolicyeine der Standardrichtlinien ist, wird std::terminate aufgerufen. Für jede andereExecutionPolicyist 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) | |
(C++20) |
|
| erstellt eine Kopie eines umgekehrten Bereichs (Funktionsschablone & Algorithmusfunktionsobjekt) | |
(C++20) |
|
(C++11) |
kopiert eine Anzahl von Elementen an eine neue Position (Funktionsschablone & Algorithmusfunktionsobjekt) |
(C++20) |
|
| kopiert den gegebenen Wert per Zuweisung in jedes Element eines Bereichs (Funktionsschablone & Algorithmusfunktionsobjekt) | |
(C++20) |
|
| kopiert einen Bereich von Elementen und lässt dabei diejenigen aus, die bestimmte Kriterien erfüllen (Funktionsschablone & Algorithmusfunktionsobjekt) | |
(C++20)(C++20) |
|
(C++20)(C++20) |
kopiert einen Bereich von Elementen an eine neue Position (Algorithmusfunktionsobjekt) |