std:: unique
|
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,
|
(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
>
|
(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.
|
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é :
-
-
Tous les itérateurs dans
[result,last)restent déréférençables .
-
Tous les itérateurs dans
|
(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)
|
| Exigences de type | ||
-
ForwardIt
doit satisfaire aux exigences de
LegacyForwardIterator
.
|
||
-
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 ) :
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
ExecutionPolicyfait partie des politiques standard , std::terminate est appelée. Pour tout autreExecutionPolicy, 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>
)
|
|
|
(C++20)
|
supprime les éléments dupliqués consécutifs dans une plage
(objet fonction algorithme) |