std:: remove, std:: remove_if
|
Défini dans l'en-tête
<algorithm>
|
||
| (1) | ||
|
template
<
class
ForwardIt,
class
T
>
ForwardIt remove ( ForwardIt first, ForwardIt last, const T & value ) ; |
(constexpr depuis C++20)
(jusqu'à C++26) |
|
|
template
<
class
ForwardIt,
class
T
=
typename
std::
iterator_traits
<
ForwardIt
>
::
value_type
>
|
(depuis C++26) | |
| (2) | ||
|
template
<
class
ExecutionPolicy,
class
ForwardIt,
class
T
>
ForwardIt remove
(
ExecutionPolicy
&&
policy,
|
(depuis C++17)
(jusqu'à C++26) |
|
|
template
<
class
ExecutionPolicy,
class
ForwardIt,
class
T
=
typename
std::
iterator_traits
|
(depuis C++26) | |
|
template
<
class
ForwardIt,
class
UnaryPred
>
ForwardIt remove_if ( ForwardIt first, ForwardIt last, UnaryPred p ) ; |
(3) | (constexpr depuis C++20) |
|
template
<
class
ExecutionPolicy,
class
ForwardIt,
class
UnaryPred
>
ForwardIt remove_if
(
ExecutionPolicy
&&
policy,
|
(4) | (depuis C++17) |
Supprime tous les éléments satisfaisant des critères spécifiques 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) |
|
Si le
type de valeur
de
|
(jusqu'à C++11) |
|
Si le type de * first n'est pas MoveAssignable , le comportement est indéfini. |
(depuis C++11) |
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 prenant result comme 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 l'intervalle des éléments à traiter |
| value | - | la valeur des éléments à supprimer |
| policy | - | la politique d'exécution à utiliser |
| p | - |
prédicat unaire qui retourne
true
si l'élément doit être supprimé.
L'expression
p
(
v
)
doit être convertible en
bool
pour chaque argument
|
| Exigences de type | ||
-
ForwardIt
doit satisfaire aux exigences de
LegacyForwardIterator
.
|
||
-
UnaryPredicate
doit satisfaire aux exigences de
Predicate
.
|
||
Valeur de retour
Itérateur après la fin pour la nouvelle plage de valeurs (si ce n'est pas end , alors il pointe vers une valeur non spécifiée, et il en va de même pour les itérateurs vers toutes les valeurs entre cet itérateur et end ).
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é. 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
| remove (1) |
|---|
template<class ForwardIt, class T = typename std::iterator_traits<ForwardIt>::value_type> ForwardIt remove(ForwardIt first, ForwardIt last, const T& value) { first = std::find(first, last, value); if (first != last) for (ForwardIt i = first; ++i != last;) if (!(*i == value)) *first++ = std::move(*i); return first; } |
| remove_if (3) |
template<class ForwardIt, class UnaryPred> ForwardIt remove_if(ForwardIt first, ForwardIt last, UnaryPred p) { first = std::find_if(first, last, p); if (first != last) for (ForwardIt i = first; ++i != last;) if (!p(*i)) *first++ = std::move(*i); return first; } |
Notes
Un appel à
remove
est généralement suivi d'un appel à la fonction membre
erase
d'un conteneur pour supprimer effectivement les éléments du conteneur. Ces deux invocations ensemble constituent ce qu'on appelle
l'idiome erase-remove
.
|
Le même effet peut également être obtenu par les fonctions non-membres suivantes :
|
(depuis C++20) |
Les fonctions membres de conteneur portant des noms similaires member functions list::remove , list::remove_if , forward_list::remove , et forward_list::remove_if suppriment les éléments retirés.
Ces algorithmes ne peuvent pas être utilisés avec des conteneurs associatifs tels que std::set et std::map car leurs types d'itérateurs ne déréférencent pas vers des types MoveAssignable (les clés dans ces conteneurs ne sont pas modifiables).
La bibliothèque standard définit également une surcharge de std::remove dans <cstdio> , qui prend un const char * et est utilisée pour supprimer des fichiers.
Parce que
std::remove
prend la
value
par référence, il peut avoir un comportement inattendu s'il s'agit d'une référence à un élément de la plage
[
first
,
last
)
.
| Macro de test de fonctionnalité | Valeur | Std | Fonctionnalité |
|---|---|---|---|
__cpp_lib_algorithm_default_value_type
|
202403
|
(C++26) | Initialisation par liste pour les algorithmes ( 1,2 ) |
Exemple
Le code suivant supprime tous les espaces d'une chaîne en décalant tous les caractères non-espace vers la gauche puis en effaçant l'excédent. Ceci est un exemple de erase-remove idiom .
#include <algorithm> #include <cassert> #include <cctype> #include <complex> #include <iomanip> #include <iostream> #include <string> #include <string_view> #include <vector> int main() { std::string str1{"Quick Red Dog"}; std::cout << "1) " << std::quoted(str1) << '\n'; const auto noSpaceEnd = std::remove(str1.begin(), str1.end(), ' '); std::cout << "2) " << std::quoted(str1) << '\n'; // Les espaces sont supprimés de la chaîne uniquement logiquement. // Notez que nous utilisons une vue, la chaîne originale n'est toujours pas réduite : std::cout << "3) " << std::quoted(std::string_view(str1.begin(), noSpaceEnd)) << ", taille : " << str1.size() << '\n'; str1.erase(noSpaceEnd, str1.end()); // Les espaces sont supprimés physiquement de la chaîne. std::cout << "4) " << std::quoted(str1) << ", taille : " << str1.size() << '\n'; std::string str2 = "Jumped\n Over\tA\vLazy \t Fox\r\n"; str2.erase(std::remove_if(str2.begin(), str2.end(), [](unsigned char x) { return std::isspace(x); }), str2.end()); std::cout << "5) " << std::quoted(str2) << '\n'; std::vector<std::complex<double>> nums{{2, 2}, {1, 3}, {4, 8}}; #ifdef __cpp_lib_algorithm_default_value_type nums.erase(std::remove(nums.begin(), nums.end(), {1, 3}), nums.end()); #else nums.erase(std::remove(nums.begin(), nums.end(), std::complex<double>{1, 3}), nums.end()); #endif assert((nums == std::vector<std::complex<double>>{{2, 2}, {4, 8}})); }
Sortie :
1) "Quick Red Dog" 2) "QuickRedDog Dog" 3) "QuickRedDog", size: 15 4) "QuickRedDog", size: 11 5) "JumpedOverALazyFox"
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 | S'applique à | Comportement publié | Comportement corrigé |
|---|---|---|---|
| LWG 283 | C++98 |
T
devait être
EqualityComparable
, mais
le type de valeur de
ForwardIt
n'est pas toujours
T
|
exige que le type de valeur de
ForwardIt
soit CopyAssignable à la place |
Voir aussi
|
copie une plage d'éléments en omettant ceux qui satisfont des critères spécifiques
(modèle de fonction) |
|
|
supprime les éléments en double consécutifs dans une plage
(modèle de fonction) |
|
|
(C++20)
(C++20)
|
supprime les éléments satisfaisant des critères spécifiques
(objet fonction algorithme) |