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
Défini dans l'en-tête <algorithm>
template < class ForwardIt >
ForwardIt unique ( ForwardIt first, ForwardIt last ) ;
(1) (constexpr depuis C++20)
template < class ExecutionPolicy, class ForwardIt >

ForwardIt unique ( ExecutionPolicy && policy,

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

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

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

Supprime tous les éléments sauf le premier de chaque groupe consécutif d'éléments équivalents de la plage [ first , last ) et retourne un itérateur pointant après le nouveau dernier élément de la plage.

1) Les éléments sont comparés en utilisant operator == .
Si operator == n'établit pas une relation d'équivalence , le comportement est indéfini.
3) Les éléments sont comparés en utilisant le prédicat binaire donné p .
Si p n'établit pas une relation d'équivalence, le comportement est indéfini.
2,4) Identique à (1,3) , mais exécuté selon la policy .
Ces surcharges participent à la résolution de surcharge seulement si toutes les conditions suivantes sont satisfaites :

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

(jusqu'à C++20)

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

(depuis C++20)

Table des matières

Explication

La suppression s'effectue en décalant les éléments de la plage de telle manière que les éléments à ne pas supprimer apparaissent au début de la plage.

  • Le décalage est effectué par copy assignment (until C++11) move assignment (since C++11) .
  • L'opération de suppression est stable : l'ordre relatif des éléments non supprimés reste inchangé.
  • La séquence sous-jacente de [ first , last ) n'est pas raccourcie par l'opération de suppression. En considérant result comme l'itérateur retourné :
  • Chaque élément de [ result , last ) a un état valide mais non spécifié, car l'affectation par déplacement peut éliminer des éléments en déplaçant à partir d'éléments qui étaient originellement dans cette plage.
(depuis C++11)

Paramètres

first, last - la paire d'itérateurs définissant la plage d'éléments à traiter
policy - la politique d'exécution à utiliser
p - prédicat binaire qui retourne ​ true si les éléments doivent être traités comme égaux.

La signature de la fonction de prédicat doit être équivalente à ce qui suit :

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

Bien que la signature n'ait pas besoin d'avoir const & , la fonction ne doit pas modifier les objets qui lui sont passés et doit pouvoir accepter toutes les valeurs de type (éventuellement const) Type1 et Type2 indépendamment de la catégorie de valeur (ainsi, Type1 & n'est pas autorisé , ni Type1 sauf si pour Type1 un déplacement est équivalent à une copie (depuis C++11) ).
Les types Type1 et Type2 doivent être tels qu'un objet de type ForwardIt puisse être déréférencé puis implicitement converti vers les deux. ​

Exigences de type
-
ForwardIt doit satisfaire aux exigences de LegacyForwardIterator .
-
Le type déréférencé de ForwardIt doit satisfaire aux exigences de MoveAssignable .

Valeur de retour

Un ForwardIt vers la nouvelle fin de la plage.

Complexité

Étant donné N comme std:: distance ( first, last ) :

1,2) Exactement max(0,N-1) comparaisons en utilisant operator == .
3,4) Exactement max(0,N-1) applications du prédicat p .

Exceptions

Les surcharges avec un paramètre de modèle nommé ExecutionPolicy signalent les erreurs comme suit :

  • Si l'exécution d'une fonction invoquée dans le cadre de l'algorithme lève une exception et que ExecutionPolicy fait partie des politiques standard , std::terminate est appelée. Pour tout autre ExecutionPolicy , le comportement est défini par l'implémentation.
  • Si l'algorithme ne parvient pas à allouer de la mémoire, std::bad_alloc est levée.

Implémentation possible

Voir également les implémentations dans libstdc++ , libc++ , et 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;
}

Notes

Un appel à unique est généralement suivi d'un appel à la fonction membre erase du conteneur pour supprimer effectivement les éléments du conteneur.

Exemple

#include <algorithm>
#include <iostream>
#include <vector>
int main()
{
    // un vecteur contenant plusieurs éléments dupliqués
    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);
    // supprimer les doublons consécutifs (adjacents)
    auto last = std::unique(v.begin(), v.end());
    // v contient maintenant {1 2 1 3 4 5 4 x x x}, où 'x' est indéterminé
    v.erase(last, v.end());
    print(2);
    // tri suivi de unique, pour supprimer tous les doublons
    std::sort(v.begin(), v.end()); // {1 1 2 3 4 4 5}
    print(3);
    last = std::unique(v.begin(), v.end());
    // v contient maintenant {1 2 3 4 5 x x}, où 'x' est indéterminé
    v.erase(last, v.end());
    print(4);
}

Sortie :

@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

Rapports de défauts

Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.

DR Applicable à Comportement publié Comportement corrigé
LWG 202 C++98 le comportement était incertain si les éléments sont
comparés en utilisant une relation de non-équivalence
le comportement est
indéfini dans ce cas

Voir aussi

trouve les deux premiers éléments adjacents qui sont égaux (ou qui satisfont un prédicat donné)
(modèle de fonction)
crée une copie d'une plage d'éléments qui ne contient pas de doublons consécutifs
(modèle de fonction)
supprime les éléments satisfaisant des critères spécifiques
(modèle de fonction)
supprime les éléments dupliqués consécutifs
(fonction membre publique de std::list<T,Allocator> )
supprime les éléments dupliqués consécutifs
(fonction membre publique de std::forward_list<T,Allocator> )
supprime les éléments dupliqués consécutifs dans une plage
(objet fonction algorithme)