Namensräume
Varianten
Aktionen

std::unique_copy

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
(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 unique_copy( InputIt first, InputIt last, OutputIt d_first );
(1) (constexpr seit C++20)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 >

ForwardIt2 unique_copy( ExecutionPolicy&& policy, ForwardIt1 first,

                        ForwardIt1 last, ForwardIt2 d_first );
(2) (seit C++17)
template< class InputIt, class OutputIt, class BinaryPred >

OutputIt unique_copy( InputIt first, InputIt last,

                      OutputIt d_first, BinaryPred p );
(3) (constexpr seit C++20)
template< class ExecutionPolicy, class ForwardIt1,

          class ForwardIt2, class BinaryPred >
ForwardIt2 unique_copy( ExecutionPolicy&& policy,
                        ForwardIt1 first, ForwardIt1 last,

                        ForwardIt2 d_first, BinaryPred p );
(4) (seit C++17)

Kopiert die Elemente aus dem Bereich [firstlast) in einen anderen Bereich, beginnend bei d_first, so dass keine aufeinanderfolgenden gleichen Elemente vorhanden sind. Nur das erste Element jeder Gruppe von gleichen Elementen wird kopiert.

1) Elemente werden mit operator== verglichen.
Wenn operator== keine Äquivalenzrelation herstellt, ist das Verhalten undefiniert.
3) Elemente werden mit dem gegebenen binären Prädikat p verglichen.
Wenn p keine Äquivalenzrelation herstellt, ist das Verhalten undefiniert.
2,4) Dasselbe wie (1,3), aber ausgeführt gemäß policy.
Diese Überladungen nehmen an der Auflösungsauflö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 *d_first = *first ungültig ist(bis C++20)*first nicht nach d_first schreibbar ist(seit C++20), ist das Programm fehlerhaft.

Wenn sich Quell- und Zielbereiche überschneiden, ist das Verhalten undefiniert.

Unter der Annahme, dass T der Werttyp von InputIt ist, ist das Verhalten undefiniert, wenn Überladung (1) oder (3) nicht alle folgenden Bedingungen erfüllt:

(bis C++20)
(seit C++20)

Inhalt

[edit] Parameter

first, last - das Iteratorenpaar, das den Quellbereich von Elementen definiert, die verarbeitet werden sollen
d_first - der Anfang des Zielbereichs
policy - die Ausführungsrichtlinie, die verwendet werden soll
p - binäre Prädikatfunktion, die ​true zurückgibt, wenn die Elemente als gleich behandelt werden sollen.

Die Signatur der Prädikatfunktion sollte äquivalent zur folgenden sein:

 bool pred(const Type1 &a, const Type2 &b);

Obwohl die Signatur nicht zwingend const & haben muss, darf die Funktion die ihr übergebenen Objekte nicht modifizieren und muss alle Werte vom Typ (möglicherweise const) Type1 und Type2 unabhängig von der Wertkategorie akzeptieren können (daher ist Type1 & nicht erlaubt, ebenso wenig wie Type1, es sei denn, für Type1 ist eine Verschiebung gleichbedeutend mit einer Kopie(seit C++11)).
Die Typen Type1 und Type2 müssen so beschaffen sein, dass ein Objekt vom Typ InputIt dereferenziert und dann implizit in beide konvertiert werden kann. ​

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.

[edit] Rückgabewert

Output-Iterator auf das Element nach dem letzten geschriebenen Element.

[edit] Komplexität

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

1,2) Genau max(0,N-1) Vergleiche mittels operator==.
3,4) Genau max(0,N-1) Anwendungen des Prädikats p.

Bei den Überladungen (2,4) kann es zu einem Performance-Verlust kommen, wenn der Werttyp von ForwardIt1 weder CopyConstructible noch CopyAssignable ist.

[edit] 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.

[edit] Mögliche Implementierung

Siehe auch die Implementierungen in libstdc++ und libc++.

[edit] Hinweise

Wenn InputIt LegacyForwardIterator erfüllt, liest diese Funktion die Eingabe erneut, um Duplikate zu erkennen.

Andernfalls, wenn OutputIt LegacyForwardIterator erfüllt und der Werttyp von InputIt derselbe ist wie der von OutputIt, vergleicht diese Funktion *d_first mit *first.

Andernfalls vergleicht diese Funktion *first mit einer lokalen Kopie des Elements.

[edit] Beispiel

#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
 
int main()
{
    std::string s1 {"A string with mmmany letters!"};
    std::cout << "Before: " << s1 << '\n';
 
    std::string s2;
    std::unique_copy(s1.begin(), s1.end(), std::back_inserter(s2),
                     [](char c1, char c2) { return c1 == 'm' && 'm' == c2; });
 
    std::cout << "After:  " << s2 << '\n';
}

Ausgabe

Before: A string with mmmany letters!
After:  A string with many letters!

[edit] 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 239 C++98 wurde das Prädikat std::distance(first, last) mal angewendet einmal weniger angewendet
(für nicht-leere Bereiche)
LWG 241 C++98 wurde der Werttyp von InputIt nicht als CopyConstructible gefordert bedingt erforderlich
LWG 538 C++98 wurde der Werttyp von InputIt nicht als CopyAssignable gefordert bedingt erforderlich
LWG 2439 C++98 wurde der Werttyp von InputIt nicht als
CopyConstructible gefordert, wenn OutputIt ein LegacyForwardIterator ist
bedingt erforderlich

[edit] Siehe auch

Findet die ersten beiden benachbarten Elemente, die gleich sind (oder eine gegebene Bedingung erfüllen)
(Funktionstempelat) [edit]
Entfernt aufeinanderfolgende doppelte Elemente in einem Bereich
(Funktionstemplate) [edit]
Kopiert einen Elementbereich an einen neuen Speicherort
(Funktionstempelat) [edit]
Erstellt eine Kopie eines Bereichs von Elementen, die keine aufeinanderfolgenden Duplikate enthält
(Algorithmus-Funktionsobjekt)[edit]