如何在迭代时从地图中删除?如何在迭代时从地图中删除?喜欢:std::map<K, V> map;for(auto i : map)
if(needs_removing(i))
// remove it from the map如果我使用map.erase它将使迭代器无效
3 回答
慕尼黑5688855
TA贡献1848条经验 获得超2个赞
我个人更喜欢这种模式,它更加清晰和简单,代价是额外的变量:
for (auto it = m.cbegin(), next_it = it; it != m.cend(); it = next_it){
++next_it;
if (must_delete)
{
m.erase(it);
}}这种方法的优点:
for循环增量器作为增量器是有意义的;
擦除操作是简单的擦除,而不是与增量逻辑混合;
在循环体的第一行之后,整个迭代中的含义
it和next_it保持固定,允许您轻松添加引用它们的其他语句,而不必头脑确定它们是否会按预期工作(当然除了it擦除后不能使用) 。
小怪兽爱吃肉
TA贡献1852条经验 获得超1个赞
简而言之“如何在迭代时从地图中删除?”
用旧地图impl:你不能
随着新的地图impl:几乎像@KerrekSB建议的那样。但他发布的内容存在一些语法问题。
来自GCC map impl(注意GXX_EXPERIMENTAL_CXX0X):
#ifdef __GXX_EXPERIMENTAL_CXX0X__ // _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 130. Associative erase should return an iterator.
/**
* @brief Erases an element from a %map.
* @param position An iterator pointing to the element to be erased.
* @return An iterator pointing to the element immediately following
* @a position prior to the element being erased. If no such
* element exists, end() is returned.
*
* This function erases an element, pointed to by the given
* iterator, from a %map. Note that this function only erases
* the element, and that if the element is itself a pointer,
* the pointed-to memory is not touched in any way. Managing
* the pointer is the user's responsibility.
*/
iterator
erase(iterator __position)
{ return _M_t.erase(__position); }#else
/**
* @brief Erases an element from a %map.
* @param position An iterator pointing to the element to be erased.
*
* This function erases an element, pointed to by the given
* iterator, from a %map. Note that this function only erases
* the element, and that if the element is itself a pointer,
* the pointed-to memory is not touched in any way. Managing
* the pointer is the user's responsibility.
*/
void
erase(iterator __position)
{ _M_t.erase(__position); }#endif旧样式和新样式的示例:
#include <iostream>#include <map>#include <vector>#include <algorithm>using namespace std;typedef map<int, int> t_myMap;typedef vector<t_myMap::key_type> t_myVec;int main() {
cout << "main() ENTRY" << endl;
t_myMap mi;
mi.insert(t_myMap::value_type(1,1));
mi.insert(t_myMap::value_type(2,1));
mi.insert(t_myMap::value_type(3,1));
mi.insert(t_myMap::value_type(4,1));
mi.insert(t_myMap::value_type(5,1));
mi.insert(t_myMap::value_type(6,1));
cout << "Init" << endl;
for(t_myMap::const_iterator i = mi.begin(); i != mi.end(); i++)
cout << '\t' << i->first << '-' << i->second << endl;
t_myVec markedForDeath;
for (t_myMap::const_iterator it = mi.begin(); it != mi.end() ; it++)
if (it->first > 2 && it->first < 5)
markedForDeath.push_back(it->first);
for(size_t i = 0; i < markedForDeath.size(); i++)
// old erase, returns void...
mi.erase(markedForDeath[i]);
cout << "after old style erase of 3 & 4.." << endl;
for(t_myMap::const_iterator i = mi.begin(); i != mi.end(); i++)
cout << '\t' << i->first << '-' << i->second << endl;
for (auto it = mi.begin(); it != mi.end(); ) {
if (it->first == 5)
// new erase() that returns iter..
it = mi.erase(it);
else
++it;
}
cout << "after new style erase of 5" << endl;
// new cend/cbegin and lambda..
for_each(mi.cbegin(), mi.cend(), [](t_myMap::const_reference it){cout << '\t' << it.first << '-' << it.second << endl;});
return 0;}打印:
main() ENTRYInit 1-1 2-1 3-1 4-1 5-1 6-1after old style erase of 3 & 4.. 1-1 2-1 5-1 6-1after new style erase of 5 1-1 2-1 6-1Process returned 0 (0x0) execution time : 0.021 sPress any key to continue.
- 3 回答
- 0 关注
- 428 浏览
添加回答
举报
0/150
提交
取消
