Gotchas:
When removing elements from containers, be careful not to saw off the branch on which you are sitting.
There is a big danger that you will remove an element to which your iterator is referring.
For example:
std::map<std::string,float> coll;
...
for (auto pos = coll.begin(); pos != coll.end(); ++pos) {
if (pos->second == value) {
coll.erase(pos); // RUNTIME ERROR !!!
}
}
Calling erase() for the element to which you are referring with pos invalidates pos as an iterator
of coll. Thus, if you use pos after removing its element without any reinitialization, all bets are off.
In fact, calling ++pos results in undefined behavior.
Solution:
(1) Since C++11, erase() always returns the value of the following element.
for (auto pos = coll.begin(); pos != coll.end(); ) {
if (pos->second == value) {
pos = coll.erase(pos); // possible only since C++11
}
else {
++pos;
}
}
(2) Before C++11, it was a design decision not to return the following position, because if not needed, it costs unnecessary time.
// remove all elements having a certain value
for (pos = coll.begin(); pos != coll.end(); ) {
if (pos->second == value) {
coll.erase(pos++);
}
else {
++pos;
}
}
本文探讨了在C++中使用迭代器删除容器元素时常见的陷阱,特别是当迭代器指向被删除元素时可能导致的问题,并提供了两种解决方案:一种适用于C++11及更高版本的方法,另一种适用于C++11之前的版本。
131

被折叠的 条评论
为什么被折叠?



