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

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

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-11-02 16:23:30367parcourir

How to Safely Erase Elements from an `std::vector` While Iterating?

Effacement d'un std :: vecteur lors d'une itération

Lors d'une itération sur un std :: vecteur et d'une tentative d'effacement d'un élément basé sur un condition, l’utilisation de la méthode v[i] peut conduire à un comportement imprévisible en raison de l’invalidation de l’itérateur. Pour résoudre ce problème efficacement, il est recommandé d'utiliser la technique d'itération appropriée à l'aide d'itérateurs.

Une approche consiste à utiliser la méthode delete(), qui renvoie un nouvel itérateur. Cela permet de continuer l'itération sans perdre la trace des éléments souhaités :

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

Notez que dans cette approche, nous devons obtenir la fin explicitement à chaque fois car l'itérateur de fin précédent peut devenir invalidé en raison d'effacements .

Une méthode alternative consiste à combiner std::remove_if avec Eraser():

<code class="cpp">iterator it = std::remove_if(begin, end, pred);
vec.erase(it, vec.end());</code>

Cette approche remplace la complexité temporelle O(N2) de l'effacement éléments individuellement avec un fonctionnement O(N) plus efficace. L'opération Eraser() supprime les éléments qui ont été marqués par l'opération Remove_if.

Dans votre cas spécifique, vous pouvez créer un prédicat personnalisé qui vérifie la condition de suppression :

<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;
};

std::vector<AguiTimedEvent>::iterator it =
    std::remove_if(timedEvents.begin(), timedEvents.end(), remove_by_caller(widget));
timedEvents.erase(it, timedEvents.end());</code>

En utilisant ces techniques, vous pouvez effacer efficacement des éléments d'un std::vector tout en itérant dessus, sans compromettre l'intégrité du processus d'itération.

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!

Déclaration:
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