Namespaces
Variants

std:: unique

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
Definiert in Header <algorithm>
template < class ForwardIt >
ForwardIt unique ( ForwardIt first, ForwardIt last ) ;
(1) (constexpr seit C++20)
template < class ExecutionPolicy, class ForwardIt >

ForwardIt unique ( ExecutionPolicy && policy,

ForwardIt first, ForwardIt last ) ;
(2) (seit C++17)
template < class ForwardIt, class BinaryPred >
ForwardIt unique ( ForwardIt first, ForwardIt last, BinaryPred p ) ;
(3) (constexpr seit C++20)
template < class ExecutionPolicy,

class ForwardIt, class BinaryPred >
ForwardIt unique ( ExecutionPolicy && policy,

ForwardIt first, ForwardIt last, BinaryPred p ) ;
(4) (seit C++17)

Entfernt alle bis auf das erste Element aus jeder aufeinanderfolgenden Gruppe äquivalenter Elemente aus dem Bereich [ first , last ) und gibt einen Iterator zurück, der über das neue Ende des Bereichs hinauszeigt.

1) Elemente werden mit operator == verglichen.
Wenn operator == keine Äquivalenzrelation definiert, ist das Verhalten undefiniert.
3) Elemente werden mit dem gegebenen binären Prädikat p verglichen.
Wenn p keine Äquivalenzrelation definiert, ist das Verhalten undefiniert.
2,4) Gleich wie (1,3) , aber ausgeführt gemäß policy .
Diese Überladungen nehmen nur dann an der Überladungsauflösung teil, 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)

Inhaltsverzeichnis

Erklärung

Das Entfernen erfolgt durch Verschieben der Elemente im Bereich in einer Weise, dass die nicht zu entfernenden Elemente am Anfang des Bereichs erscheinen.

  • Das Verschieben erfolgt durch copy assignment (until C++11) move assignment (since C++11) .
  • Der Entfernungsvorgang ist stabil: Die relative Reihenfolge der nicht zu entfernenden Elemente bleibt gleich.
  • Die zugrundeliegende Sequenz von [ first , last ) wird durch den Entfernungsvorgang nicht verkürzt. Mit result als zurückgegebenem Iterator:
  • Jedes Element von [ result , last ) hat einen gültigen, aber unspezifizierten Zustand, da Move-Zuweisung Elemente entfernen kann, indem von Elementen bewegt wird, die ursprünglich in diesem Bereich waren.
(seit C++11)

Parameter

first, last - das Paar von Iteratoren, das den Bereich der zu verarbeitenden Elemente definiert
policy - die zu verwendende Ausführungsrichtlinie
p - binäres Prädikat, das ​ true zurückgibt, wenn die Elemente als gleich behandelt werden sollen.

Die Signatur der Prädikatfunktion sollte äquivalent zu Folgendem sein:

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

Obwohl die Signatur nicht const & benötigt, darf die Funktion die übergebenen Objekte nicht modifizieren und muss alle Werte des Typs (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 äquivalent zu einer Kopie (seit C++11) ).
Die Typen Type1 und Type2 müssen so beschaffen sein, dass ein Objekt vom Typ ForwardIt dereferenziert und dann implizit in beide konvertiert werden kann. ​

Typanforderungen
-
ForwardIt muss die Anforderungen von LegacyForwardIterator erfüllen.
-
Der Typ des dereferenzierten ForwardIt muss die Anforderungen von MoveAssignable erfüllen.

Rückgabewert

Ein ForwardIt zum neuen Ende des Bereichs.

Komplexität

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

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

Ausnahmen

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

  • Wenn die Ausführung einer als Teil des Algorithmus aufgerufenen Funktion eine Exception wirft und ExecutionPolicy einer der Standard-Policies ist, wird std::terminate aufgerufen. Für jede andere ExecutionPolicy ist das Verhalten implementierungsdefiniert.
  • Wenn der Algorithmus keinen Speicher allokieren kann, wird std::bad_alloc geworfen.

Mögliche Implementierung

Siehe auch die Implementierungen in libstdc++ , libc++ , und MSVC STL .

unique (1)
template<class ForwardIt>
ForwardIt unique(ForwardIt first, ForwardIt last)
{
    if (first == last)
        return last;
    ForwardIt result = first;
    while (++first != last)
        if (!(*result == *first) && ++result != first)
            *result = std::move(*first);
    return ++result;
}
unique (3)
template<class ForwardIt, class BinaryPredicate>
ForwardIt unique(ForwardIt first, ForwardIt last, BinaryPredicate p)
{
    if (first == last)
        return last;
    ForwardIt result = first;
    while (++first != last)
        if (!p(*result, *first) && ++result != first)
            *result = std::move(*first);
    return ++result;
}

Hinweise

Ein Aufruf von unique wird typischerweise gefolgt von einem Aufruf der erase -Memberfunktion eines Containers, um tatsächlich Elemente aus dem Container zu entfernen.

Beispiel

#include <algorithm>
#include <iostream>
#include <vector>
int main()
{
    // ein Vektor mit mehreren doppelten Elementen
    std::vector<int> v{1, 2, 1, 1, 3, 3, 3, 4, 5, 4};
    auto print = [&](int id)
    {
        std::cout << "@" << id << ": ";
        for (int i : v)
            std::cout << i << ' ';
        std::cout << '\n';
    };
    print(1);
    // entferne aufeinanderfolgende (benachbarte) Duplikate
    auto last = std::unique(v.begin(), v.end());
    // v enthält nun {1 2 1 3 4 5 4 x x x}, wobei 'x' undefiniert ist
    v.erase(last, v.end());
    print(2);
    // sortieren gefolgt von unique, um alle Duplikate zu entfernen
    std::sort(v.begin(), v.end()); // {1 1 2 3 4 4 5}
    print(3);
    last = std::unique(v.begin(), v.end());
    // v enthält nun {1 2 3 4 5 x x}, wobei 'x' undefiniert ist
    v.erase(last, v.end());
    print(4);
}

Ausgabe:

@1: 1 2 1 1 3 3 3 4 5 4
@2: 1 2 1 3 4 5 4
@3: 1 1 2 3 4 4 5
@4: 1 2 3 4 5

Fehlerberichte

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

DR Angewendet auf Verhalten wie veröffentlicht Korrektes Verhalten
LWG 202 C++98 das Verhalten war unklar, wenn die Elemente
mit einer Nicht-Äquivalenzrelation verglichen werden
das Verhalten ist
in diesem Fall undefiniert

Siehe auch

findet die ersten zwei benachbarten Elemente, die gleich sind (oder ein gegebenes Prädikat erfüllen)
(Funktions-Template)
erstellt eine Kopie eines Bereichs von Elementen, die keine aufeinanderfolgenden Duplikate enthält
(Funktions-Template)
entfernt Elemente, die bestimmte Kriterien erfüllen
(Funktions-Template)
entfernt aufeinanderfolgende doppelte Elemente
(öffentliche Elementfunktion von std::list<T,Allocator> )
entfernt aufeinanderfolgende doppelte Elemente
(öffentliche Elementfunktion von std::forward_list<T,Allocator> )
entfernt aufeinanderfolgende doppelte Elemente in einem Bereich
(Algorithmus-Funktionsobjekt)