反向遍历 std::map 的时候删除迭代器
2023.4.19

decltype(mp)::iterator p = ++mp.erase(++it.base());
it = std::make_reverse_iterator(p);
demo
#include <bits/stdc++.h>
int main() {
std::map<int, int> mp{{1, 2}, {3, 1}, {2, 1}};
for (auto it = mp.rbegin(); it != mp.rend(); ) {
if (it->first == 2) {
decltype(mp)::iterator p = ++mp.erase(++it.base());
it = std::make_reverse_iterator(p);
} else {
it ++;
}
}
for (auto &[k, v] : mp) {
std::cout << k << ' ' << v << '\n';
}
return 0;
}
原理
std::map::erase 要求传入 {, const_}iterator 因此这个情景下的 {, const_}reverse_iterator 不奏效。所以考虑转换成 iterator 之后再 erase,之后再转回 reverse_iterator。根据两种迭代器的对应规则,有:

也就是说,直接对反向迭代器 it 调用 std::make_reverse_iterator 得到的并不是期待的,而 std::next(it) 才对应正确的值。
另外要从反向迭代器得到正向迭代器,除了 std::make_reverse_iterator 再翻转一次也可以直接使用 std::reverse_iterator 对应的成员函数 base() 得到。
