web-dev-qa-db-ja.com

std :: vectorからの生のポインタの削除

私は次のパターンを持っています:

  1. std::vectorオブジェクトへの生のポインタが含まれています(生のポインタは「悪」ですが、保守が必要なレガシーソフトウェアです)。
  2. 次に、ベクター内の各要素についてテストを行う必要があります。テストが成功した場合は、ポインターを使用して何かを実行し、それを削除してからベクターから削除します。

疑似コード:

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

このためのすてきなクリーンなコードを思いつくことができません。

このリンク は異なるアプローチを提供しますが、それらはすべて多かれ少なかれ面倒です。

私が今使っている面倒なソリューション:

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

あなたがintポインタのベクトルを持っていると仮定します。これが私の解決策です:

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

複雑にしないでおく。 YAGNI。より一般的で複雑なバージョンの問題を偶然に解決する理由はありませんが、それが必要になるか(ヒント:必要ありません)、あいまいなSTLメソッドを探します(そうでない場合はwish to )。

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

私が使用するいくつかのアプローチ:

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.