Maison > développement back-end > C++ > Comment supprimer en toute sécurité des éléments d'un « std :: vector » lors d'une itération ?

Comment supprimer en toute sécurité des éléments d'un « std :: vector » lors d'une itération ?

DDD
Libérer: 2024-11-01 20:27:02
original
244 Les gens l'ont consulté

How to Safely Remove Elements from a `std::vector` While Iterating?

Itération et effacement de std::vector

L'approche recommandée pour itérer dans un std::vector consiste à utiliser des itérateurs. Cependant, effacer des éléments lors d'une itération peut invalider l'itérateur.

Pour résoudre ce problème, il est crucial de modifier l'affectation de l'itérateur après avoir effacé un élément, comme démontré ci-dessous :

<code class="cpp">for (iterator it = begin; it != end(container) /* !!! */; )
{
    if (it->somecondition())
    {
        it = vec.erase(it);  // Returns the new iterator to continue from.
    }
    else
    {
        ++it;
    }
}</code>
Copier après la connexion

Il est important de notez que la fin du conteneur doit être recalculée à chaque fois après avoir effacé un élément.

Une alternative plus efficace consiste à combiner std::remove_if et Eraser():

<code class="cpp">iterator it = std::remove_if(begin, end, pred);
vec.erase(it, vec.end());</code>
Copier après la connexion

Cette approche change la complexité temporelle de O(N^2) à O(N). Voici un exemple de prédicat pour supprimer des éléments :

<code class="cpp">struct predicate
{
    bool operator()(const T& pX) const
    {
        return pX.shouldIBeRemoved();
    }
};</code>
Copier après la connexion

Pour votre cas spécifique, vous pouvez utiliser une approche plus générique :

<code class="cpp">class remove_by_caller
{
public:
    remove_by_caller(AguiWidgetBase* pWidget) : mWidget(pWidget) {}
    template <typename T>
    bool operator()(const T& pX) const
    {
        return pX.getCaller() == mWidget;
    }
private:
    AguiWidgetBase* mWidget;
};</code>
Copier après la connexion

Utiliser cette approche :

<code class="cpp">std::vector<AguiTimedEvent>::iterator it =
    std::remove_if(timedEvents.begin(), timedEvents.end(), remove_by_caller(widget));
timedEvents.erase(it, timedEvents.end());</code>
Copier après la connexion

De plus, les expressions lambda peuvent simplifier ce processus, comme pris en charge à la fois par Boost et C 11.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal