下面的文字是 Effective STL Item 9 的片段
ofstream logFile; // log file to write to
AssocContainer<int> c;
…
for (AssocContainer<int>::iterator i = c.begin(); // loop conditions are the
i !=c.end();){ //same as before
if (badValue(*i)){
logFile << "Erasing " << *i <<'\n'; // write log file
c.erase(i++); // erase element
}
else ++i;
}
现在给我们带来麻烦的是 vector、string 和 deque。我们不能再使用 erase-remove 习惯用法了,因为没有办法通过 erase 或 remove 来写入日志文件。此外,我们不能使用刚刚为关联容器开发的循环,因为它会为 vector 、字符串和双端队列产生未定义的行为!回想一下,对于这样的容器,调用 erase 不仅会使指向被删除元素的所有迭代器无效,还会使被删除元素之外的所有迭代器无效。在我们的例子中,这包括 i 之外的所有迭代器。我们编写 i++、++I 或您能想到的任何其他内容都没关系,因为生成的迭代器均无效。
我们必须对 vector 、字符串和双端队列采取不同的策略。特别是,我们必须利用 erase 的返回值。该返回值正是我们所需要的:它是一个有效的迭代器,一旦完成删除,它就会指向被删除元素之后的元素。换句话说,我们这样写:
for (SeqContainer<int>::iterator i = c.beqin();
i != c.end();){
if (badValue(*i)){
logFile << "Erasing " << *i << '\n';
i = c.erase(i); // keep i valid by assigning
} //erase's return value to it
else ++i;
}
我的问题是作者提到如果我们在 vector 、字符串、双端队列上使用删除“使所有指向被删除元素的迭代器无效,它也使所有超出被删除元素的迭代器无效”,但如果我们使用返回值,后面的语句是矛盾的erase 之后我们就可以使用它了,问题:“erase 不是使所有超出已删除元素的指针无效吗?
最佳答案
Question: "Isn't erase invalidate all pointer beyond erased element?
可能会,但在这种情况下与您无关。 erase()
可能会使在调用 erase()
之前获得的现有迭代器无效,但是 erase()
本身返回的是一个新的、有效的任何情况下的迭代器。
关于c++ - 序列容器的重新分级删除功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47575760/