std::ranges::remove, std::ranges::remove_if
| Défini dans l'en-tête <algorithm>
|
||
| Signature d'appel |
||
template< std::permutable I, std::sentinel_for<I> S,
class T, class Proj = std::identity >
requires std::indirect_binary_predicate
<ranges::equal_to, std::projected<I, Proj>, const T*>
constexpr ranges::subrange<I>
remove( I first, S last, const T& value, Proj proj = {} );
|
(1) | (depuis C++20) (jusqu'à C++26) |
template< std::permutable I, std::sentinel_for<I> S,
class Proj = std::identity,
class T = std::projected_value_t<I, Proj> >
requires std::indirect_binary_predicate
<ranges::equal_to, std::projected<I, Proj>, const T*>
constexpr ranges::subrange<I>
remove( I first, S last, const T& value, Proj proj = {} );
|
(depuis C++26) | |
template< ranges::forward_range R,
class T, class Proj = std::identity >
requires std::permutable<ranges::iterator_t<R>> &&
std::indirect_binary_predicate
<ranges::equal_to,
std::projected<ranges::iterator_t<R>, Proj>, const T*>
constexpr ranges::borrowed_subrange_t<R>
remove( R&& r, const T& value, Proj proj = {} );
|
(2) | (depuis C++20) (jusqu'à C++26) |
template< ranges::forward_range R,
class Proj = std::identity,
class T = std::projected_value_t<ranges::iterator_t<R>, Proj> >
requires std::permutable<ranges::iterator_t<R>> &&
std::indirect_binary_predicate
<ranges::equal_to,
std::projected<ranges::iterator_t<R>, Proj>, const T*>
constexpr ranges::borrowed_subrange_t<R>
remove( R&& r, const T& value, Proj proj = {} );
|
(depuis C++26) | |
template< std::permutable I, std::sentinel_for<I> S,
class Proj = std::identity,
std::indirect_unary_predicate<std::projected<I, Proj>> Pred >
constexpr ranges::subrange<I>
remove_if( I first, S last, Pred pred, Proj proj = {} );
|
(3) | (depuis C++20) |
template< ranges::forward_range R,
class Proj = std::identity,
std::indirect_unary_predicate
<std::projected<ranges::iterator_t<R>, Proj>> Pred >
requires std::permutable<ranges::iterator_t<R>>
constexpr ranges::borrowed_subrange_t<R>
remove_if( R&& r, Pred pred, Proj proj = {} );
|
(4) | (depuis C++20) |
Supprime tous les éléments satisfaisant des critères spécifiques de la plage [first, last) et renvoie une sous-plage [ret, last), où ret est un itérateur après-la-fin pour la nouvelle fin de la plage.
value, en utilisant std::invoke(proj, *i) == value pour comparer.std::invoke(pred, std::invoke(proj, *i)) renvoie true.r comme plage, comme si on utilisait ranges::begin(r) comme first et ranges::end(r) comme last.La suppression est effectuée en décalant (par affectation de déplacement) les éléments de la plage de telle sorte que les éléments qui ne doivent pas être supprimés apparaissent au début de la plage. L'ordre relatif des éléments qui restent est préservé et la taille physique du conteneur est inchangée. Les itérateurs pointant vers un élément entre la nouvelle fin logique et la fin physique de la plage sont toujours déréférençables, mais les éléments eux-mêmes ont des valeurs non spécifiées (selon la post-condition de MoveAssignable).
Les entités de type fonction décrites sur cette page sont des objets fonctions d'algorithme (informellement appelés niebloids), c'est-à-dire :
- Les listes d'arguments de modèle explicites ne peuvent pas être spécifiées lors de l'appel de l'une d'elles.
- Aucune d'elles n'est visible par la recherche dépendante des arguments.
- Lorsque l'une d'elles est trouvée par une recherche normale non qualifiée comme le nom à gauche de l'opérateur d'appel de fonction, la recherche dépendante des arguments est inhibée.
Paramètres
| first, last | - | la paire itérateur-sentinelle définissant la plage des éléments à traiter |
| r | - | la plage d'éléments à traiter |
| value | - | la valeur des éléments à supprimer |
| pred | - | prédicat à appliquer aux éléments projetés |
| proj | - | projection à appliquer aux éléments |
Valeur de retour
{
ret, last
}
, où
[
first
,
ret
)
est le sous-intervalle résultant après suppression, et les éléments dans le sous-intervalle
[
ret
,
last
)
sont tous dans un état valide mais non spécifié, c'est-à-dire que
[
ret
,
last
)
est le sous-intervalle à effacer.
Complexité
Exactement N applications du prédicat correspondant et de toute projection, où N = ranges:: distance ( first, last ) , et N - 1 opérations de déplacement au pire.
Notes
Un appel à
ranges::remove
est généralement suivi d'un appel à la fonction membre
erase
du conteneur, qui efface les valeurs non spécifiées et réduit la taille
physique
du conteneur pour correspondre à sa nouvelle taille
logique
. Ces deux invocations constituent ensemble ce qu'on appelle l'
idiome erase-remove
, qui peut être réalisé par la fonction libre
std::erase
qui possède des
surcharges
pour tous les conteneurs
séquentiels
standards, ou
std::erase_if
qui possède des
surcharges
pour
tous
les conteneurs standards.
Les fonctions membres de conteneur de nom similaire 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 généralement pas être utilisés avec des conteneurs associatifs tels que std::set et std::map car leurs types d'itérateurs ne se déréférencent pas vers des types MoveAssignable (les clés dans ces conteneurs ne sont pas modifiables).
Parce que
ranges::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
)
.
Implémentation possible
| supprimer (1,2) |
|---|
struct remove_fn { template<std::permutable I, std::sentinel_for<I> S, class Proj = std::identity, class T = std::projected_value_t<I, Proj>> requires std::indirect_binary_predicate <ranges::equal_to, std::projected<I, Proj>, const T*> constexpr ranges::subrange<I> operator()(I first, S last, const T& value, Proj proj = {}) const { first = ranges::find(std::move(first), last, value, proj); if (first != last) { for (I i{std::next(first)}; i != last; ++i) if (value != std::invoke(proj, *i)) { *first = ranges::iter_move(i); ++first; } } return {first, last}; } template<ranges::forward_range R, class Proj = std::identity, class T = std::projected_value_t<ranges::iterator_t<R>, Proj>> requires std::permutable<ranges::iterator_t<R>> && std::indirect_binary_predicate <ranges::equal_to, std::projected<ranges::iterator_t<R>, Proj>, const T*> constexpr ranges::borrowed_subrange_t<R> operator()(R&& r, const T& value, Proj proj = {}) const { return (*this)(ranges::begin(r), ranges::end(r), value, std::move(proj)); } }; inline constexpr remove_fn remove {}; |
| remove_if (3,4) |
struct remove_if_fn { template<std::permutable I, std::sentinel_for<I> S, class Proj = std::identity, std::indirect_unary_predicate<std::projected<I, Proj>> Pred> constexpr ranges::subrange<I> operator()(I first, S last, Pred pred, Proj proj = {}) const { first = ranges::find_if(std::move(first), last, pred, proj); if (first != last) { for (I i{std::next(first)}; i != last; ++i) if (!std::invoke(pred, std::invoke(proj, *i))) { *first = ranges::iter_move(i); ++first; } } return {first, last}; } template<ranges::forward_range R, class Proj = std::identity, std::indirect_unary_predicate <std::projected<ranges::iterator_t<R>, Proj>> Pred> requires std::permutable<ranges::iterator_t<R>> constexpr ranges::borrowed_subrange_t<R> operator()(R&& r, Pred pred, Proj proj = {}) const { return (*this)(ranges::begin(r), ranges::end(r), pred, std::move(proj)); } }; inline constexpr remove_if_fn remove_if {}; |
Notes
| 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
#include <algorithm> #include <cassert> #include <complex> #include <cctype> #include <iomanip> #include <iostream> #include <string> #include <string_view> #include <vector> int main() { std::string v1{"Aucun - Diagnostic - Requis"}; std::cout << std::quoted(v1) << " (v1, taille : " << v1.size() << ")\n"; const auto ret = std::ranges::supprimer(v1, ' '); std::cout << std::quoted(v1) << " (v1 après `remove`, taille : " << v1.size() << ")\n"; std::cout << ' ' << std::string(std::distance(v1.begin(), ret.begin()), '^') << '\n'; v1.erase(ret.begin(), ret.end()); std::cout << std::quoted(v1) << " (v1 après `erase`, taille : " << v1.size() << ")\n\n"; // remove_if avec prédicat unaire personnalisé : auto rm = [](char c) { return !std::isupper(c); }; std::string v2{"Substitution Failure Is Not An Error"}; std::cout << std::quoted(v2) << " (v2, taille : " << v2.size() << ")\n"; const auto [first, last] = std::ranges::remove_if(v2, rm); std::cout << std::quoted(v2) << " (v2 après `remove_if`, taille : " << v2.size() << ")\n"; std::cout << ' ' << std::string(std::distance(v2.begin(), first), '^') << '\n'; v2.erase(first, last); std::cout << std::quoted(v2) << " (v2 après `erase`, taille : " << v2.size() << ")\n\n"; // création d'une vue dans un conteneur qui est modifié par `remove_if` : for (std::string s : {"Optimisation des Petits Objets", "Paramètre de Modèle Non-Type"}) std::cout << std::quoted(s) << " => " << std::string_view{begin(s), std::ranges::remove_if(s, rm).begin()} << '\n'; std::vector<std::complex<double>> nums{{2, 2}, {1, 3}, {4, 8}}; #ifdef __cpp_lib_algorithm_default_value_type auto e = std::ranges::supprimer(nums, {1, 3}); // T est déduit #else auto e = std::ranges::supprimer(nums, std::complex<double>{1, 3}); #endif nums.erase(e.begin(), e.end()); assert((nums == std::vector<std::complex<double>>{{2, 2}, {4, 8}})); }
Sortie possible :
"No _ Diagnostic _ Required" (v1, taille : 26) "No_Diagnostic_Requiredired" (v1 après `remove`, taille : 26) ^^^^^^^^^^^^^^^^^^^^^^ "No_Diagnostic_Required" (v1 après `erase`, taille : 22) "Substitution Failure Is Not An Error" (v2, taille : 36) "SFINAEtution Failure Is Not An Error" (v2 après `remove_if`, taille : 36) ^^^^^^ "SFINAE" (v2 après `erase`, taille : 6) "Small Object Optimization" => SOO "Non-Type Template Parameter" => NTTP
Voir aussi
|
(C++20)
(C++20)
|
copie une plage d'éléments en omettant ceux qui satisfont des critères spécifiques
(objet fonction algorithme) |
|
(C++20)
|
supprime les éléments en double consécutifs dans une plage
(objet fonction algorithme) |
|
supprime les éléments satisfaisant des critères spécifiques
(modèle de fonction) |