Maison > développement back-end > C++ > le corps du texte

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

Mary-Kate Olsen
Libérer: 2024-11-02 16:23:30
original
423 Les gens l'ont consulté

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>
Copier après la connexion

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>
Copier après la connexion

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>
Copier après la connexion

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!

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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal