标准库容器允许我们删除
由迭代器first
和last
表示的范围。
std::vector<foo> bar;
// first it last it
bar.erase(bar.begin(), bar.end());
标准规定first
迭代器必须有效并且 可解引用,而last
只需要有效。但是,如果 first == last
则 first
不需要取消引用,因为 erase
是空操作。这意味着以下内容是合法的:
bar.erase(bar.end(), bar.end());
但是,如果我只想删除一个元素而不是一个范围,则迭代器必须是有效的并且可解引用,从而导致以下未定义的行为:
bar.erase(bar.end());
为什么这不只是空操作?这是标准委员会的疏忽,将在未来的语言修订版中解决,还是我没有看到重点的故意设计决定?
据我所知,它没有提供任何好处,但在执行以下操作时会造成额外的麻烦:
bar.erase(std::find(bar.begin(), bar.end(), thing));
最佳答案
C++ 习惯于在其标准库中留下任何额外的工作,也称为“你不用为你不用的东西付费”。在这种情况下,单迭代器版本需要将迭代器与结束迭代器进行比较。在大多数情况下,此检查是多余的,这是未使用的额外工作,尽管工作量很小。
erase(iterator it):
if it != end: // we can't avoid this check now
// erase element
在重载取范围的情况下,在结束前自然停止。一个简单的实现可能如下所示:
erase(iterator first, iterator last):
while first != last:
erase(first++);
它需要某种方式来知道何时停止删除。在某些情况下,它可能更智能,例如 memmove
内存块覆盖已删除的内存而无需分支,但这只会在特定场景中发生。
另请注意,与其他方式相比,由此构建检查版本要容易得多:
checked_erase(Container cont, iterator it):
if it != cont.end():
cont.erase(it);
关于c++ - 删除结束迭代器是对标准的疏忽还是设计决策?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36681156/