Namespaces
Variants

std::remove, std::remove_if

De fr.cppreference.net
 
 
Bibliothèque d'algorithmes
Algorithmes contraints et algorithmes sur intervalles (C++20)
Algorithmes contraints, ex. ranges::copy, ranges::sort, ...
Opérations de séquence non modifiantes    
Opérations par lot
(C++17)
Opérations de recherche
Opérations de séquence modifiantes
Opérations de copie
(C++11)
(C++11)
Opérations d'échange
Opérations de transformation
Opérations de génération
Opérations de suppression
Opérations de changement d'ordre
(jusqu'à C++17)(C++11)
(C++20)(C++20)
Opérations d'échantillonnage
(C++17)

Opérations de tri et apparentées
Opérations de partitionnement
(C++11)    

Opérations de tri
Opérations de recherche dichotomique
(sur intervalles partitionnés)
Opérations d'ensemble (sur intervalles triés)
Opérations de fusion (sur intervalles triés)
Opérations de tas
Opérations de minimum/maximum
(C++11)
(C++17)
Opérations de comparaison lexicographique
Opérations de permutation


 
Défini dans l'en-tête <algorithm>
template< class ForwardIt, class T >
ForwardIt remove( ForwardIt first, ForwardIt last, const T& value );
(1) (jusqu'à C++26)
(constexpr depuis C++20)
template< class ForwardIt, class T = typename std::iterator_traits
                                         <ForwardIt>::value_type >
constexpr ForwardIt remove( ForwardIt first, ForwardIt last,
                            const T& value );
(depuis C++26)
template< class ExecutionPolicy, class ForwardIt, class T >
ForwardIt remove( ExecutionPolicy&& policy,
                  ForwardIt first, ForwardIt last, const T& value );
(2) (depuis C++17)
(jusqu'à C++26)
template< class ExecutionPolicy, class ForwardIt,
          class T = typename std::iterator_traits
                        <ForwardIt>::value_type >
ForwardIt remove( ExecutionPolicy&& policy,
                  ForwardIt first, ForwardIt last, const T& value );
(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,
                     ForwardIt first, ForwardIt last, UnaryPred p );
(4) (depuis C++17)

Supprime tous les éléments répondant à des critères spécifiques de la plage [firstlast) et renvoie un itérateur pointant après la fin pour la nouvelle fin de la plage.

1) Supprime tous les éléments qui sont égaux à value (en utilisant operator==).
3) Supprime tous les éléments pour lesquels le prédicat p renvoie true.
2,4) Identique à (1,3), mais exécuté selon policy.
Ces surcharges ne participent à la résolution de surcharge que si la valeur de l'expression suivante est true:

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>

(jusqu'à C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>

(depuis C++20)


Si le type valeur de ForwardIt n'est pas CopyAssignable, le comportement est indéfini.

(jusqu'à C++11)

Si le type de *first n'est pas MoveAssignable, le comportement est indéfini.

(depuis C++11)

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é :
  • 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 initialement dans cette plage.
(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 v de type (éventuellement const) VT , où VT est le type de valeur de ForwardIt , indépendamment de la catégorie de valeur , et ne doit pas modifier v . Ainsi, un type de paramètre VT & n'est pas autorisé , pas plus que VT sauf si pour VT un déplacement est équivalent à une copie (depuis C++11) . ​

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 ) :

1,2) Exactement N comparaisons en utilisant operator == .
3,4) Exactement N 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é. 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

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 & objet fonction d'algorithme)
supprime les éléments en double consécutifs dans une plage
(modèle de fonction & objet fonction d'algorithme)
supprime les éléments qui satisfont à des critères spécifiques
(objet fonction d'algorithme)