假设我有一个hash_map和一个像
这样的代码// i is an iterator
i = hash_map.erase(i)
但是GCC的STL不会在擦除中返回迭代器,而是一个空白。现在是像
这样的代码hash_map.erase(i++)
安全(即不会使迭代器无效或做任何其他意外或不愉快的事情)?请注意这是一个hash_map。
答案 0 :(得分:6)
是的,这是安全的,因为在删除当前值之前,i
的值将被设置为下一个值。
根据SGI documentation about hashed containers失效不会发生非擦除元素,甚至也不会调整大小(没有关于插入是否会导致调整大小的说法,所以要小心我承认作为一种可能性)---但在后一种情况下,迭代顺序将会改变。但这不适用于此,除非您在遍历或其他事情期间不遗余力地调整容器大小。 : - )
答案 1 :(得分:2)
您可以封装擦除,为您使用的所有容器提供相同的界面:
namespace detail {
template<typename Container, typename R>
struct SelectErase {
// by default, assume the next iterator is returned
template<typename Iterator>
Iterator erase(Container& c, Iterator where) {
return c.erase(where);
}
};
// specialize on return type void
template<typename Container>
struct SelectErase<Container, void> {
template<typename Iterator>
Iterator erase(Container& c, Iterator where) {
Iterator next (where);
++next;
c.erase(where);
return next;
}
};
template<typename I, typename Container, typename R>
SelectErase<Container,R> select_erase(R (Container::*)(I)) {
return SelectErase<Container,R>();
}
} // namespace detail
template<typename Container, typename Iterator>
Iterator erase(Container& container, Iterator where) {
return detail::select_erase<Iterator>(&Container::erase).erase(container, where);
}
这需要:
答案 2 :(得分:-4)
在游行中讨厌下雨,但我不认为你的建议是安全的。
i ++是后增量运算符,这意味着在调用erase之后i递增。但擦除会使指向被擦除元素的所有迭代器无效。因此,当i增加时,它不再有效。
如果你很幸运,它可能会偶然正常工作,直到有一天它不再存在。
据我所知,除此之外没有办法解决这个问题:
// tmp and i are both iterators
tmp = i;
++i;
hash_map.erase(tmp);