web-dev-qa-db-fra.com

Suppression de pointeurs bruts de std :: vector

J'ai le schéma suivant:

  1. J'ai un std::vector contenant des pointeurs bruts vers des objets (je sais que les pointeurs bruts sont "mauvais", mais c'est un logiciel hérité qui doit être maintenu).
  2. Maintenant, pour chaque élément du vecteur, je dois faire un test et si le test est positif, faites quelque chose avec le pointeur, supprimez-le puis supprimez-le du vecteur:

Pseudo-code:

for each pointer in vector
{
  if (SomeTest(pointer))
  {
     DoSomething(pointer)
     delete pointer
     remove pointer from vector
  }
}

Je ne suis pas en mesure de trouver un code propre agréable pour cela.

Ce lien propose différentes approches, mais elles me semblent toutes plus ou moins lourdes.

Solution lourde que j'utilise maintenant:

for(auto &  p : v)
{
   if (SomeTest(p))
   {
       DoSomething(p);
       delete p;
       p = nullptr;
   }
}

v.erase(std::remove(v.begin(), v.end(), nullptr), v.end());
20
Jabberwocky

Supposons que vous ayez un vecteur de pointeur int. Voici ma solution:

vector<int*> vpi;

for (vector<int*>::iterator it = vpi.begin(); it != vpi.end(); )
{
    if (SomeTest(*it))
    {
        DoSomething(*it)
        int* old = *it;
        it = vpi.erase(it);
        delete old;
    } else
    {
       it++;
    }
}
0
Loc Tran

Rester simple. YAGNI. Aucune raison de résoudre une version plus générique et compliquée du problème au cas où vous en auriez besoin (indice: vous ne le ferez pas), ou à la recherche de méthodes STL obscures (enfin, à moins que vous souhait à ).

size_t target = 0;
for (size_t idx = 0; idx < v.size(); idx++) {
    if (should_delete(v[idx]))
        delete v[idx];
    else
        v[target++] = v[idx];
}
v.resize(target);
0
jick

Une approche que j'utiliserais:

for (auto i = vector.begin(); i != vector.end(); ++i) {
  if (SomeTest(*i)) {
    DoSomething(*i);
    delete *i;
    *i = nullptr;
  }
}
vector.erase(std::remove(vector.begin(), vector.end(), nullptr), vector.end());
0
S.M.