web-dev-qa-db-ja.com

STD :: Mapからアイテムを絞り込む方法?

私はおおよそ次のコードを持っています。これをより効率的にすることもできますか?おそらくstd::remove_if?それを通過しながら地図からアイテムを削除できますか?一時マップを使用しないでください。

typedef std::map<Action, What> Actions;
static Actions _actions;

bool expired(const Actions::value_type &action)
{
  return <something>;
}

void bar(const Actions::value_type &action)
{
  // do some stuff
}

void foo()
{
  // loop the actions finding expired items
  Actions actions;
  BOOST_FOREACH(Actions::value_type &action, _actions)
  {
    if (expired(action))
      bar(action);
    else
      actions[action.first]=action.second;
    }
  }
  actions.swap(_actions);
}
 _
27

ERASE()を使用できますが、Boost_Foreachが無効化されたイテレータを処理する方法はわかりません。 Map :: Eraseのドキュメント 消去されたイテレータのみが無効になると述べているため、他のものはOKになります。これが私が内側のループを再構築する方法です:

Actions::iterator it = _actions.begin();
while (it != _actions.end())
{
  if (expired(*it))
  {
    bar(*it);
    Actions::iterator toerase = it;
    ++it;
    _actions.erase(toerase);
  }
  else
    ++it;
}
 _
30
Mark Ransom

マークransomアルゴリズムの変動は一時的な必要なしに。

for(Actions::iterator it = _actions.begin();it != _actions.end();)
{
    if (expired(*it))
    {
        bar(*it);
        _actions.erase(it++);  // Note the post increment here.
                               // This increments 'it' and returns a copy of
                               // the original 'it' to be used by erase()
    }
    else
    {
        ++it;  // Use Pre-Increment here as it is more effecient
               // Because no copy of it is required.
    }
}
 _
53
Martin York

誰が知っていないようなものではないことは、Eraseが任意のコンテナで使用されたときに、有効な、有効なイテレータを返すことです。

Actions::iterator it = _actions.begin();
while (it != _actions.end())
{
  if (expired(*it))
  {
    bar(*it);
    it = _actions::erase(it);
  }
  else
    ++it;
}
 _

Actions.end()は、イテレータの安定性が保証されていないので、この場合はおそらく良い計画ではありません。

2
coppro