私はおおよそ次のコードを持っています。これをより効率的にすることもできますか?おそらく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);
}
_
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;
}
_
マーク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.
}
}
_
誰が知っていないようなものではないことは、Eraseが任意のコンテナで使用されたときに、有効な、有効なイテレータを返すことです。
Actions::iterator it = _actions.begin();
while (it != _actions.end())
{
if (expired(*it))
{
bar(*it);
it = _actions::erase(it);
}
else
++it;
}
_
Actions.end()は、イテレータの安定性が保証されていないので、この場合はおそらく良い計画ではありません。