如何在迭代时从地图中删除?如何在迭代时从地图中删除?喜欢: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 关注
- 346 浏览
添加回答
举报
0/150
提交
取消