标准库容器允许我们使用迭代器 erasefirst 表示的 last 范围。

std::vector<foo> bar;
//         first it     last it
bar.erase(bar.begin(), bar.end());

标准规定 first 迭代器必须有效且可取消引用,而 last 只需要有效。但是,如果 first == lastfirst 不需要可取消引用,因为 erase 是空操作。这意味着以下内容是合法的:
bar.erase(bar.end(), bar.end());

但是,如果我只想擦除一个元素而不是一个范围,则迭代器必须有效且可取消引用,从而产生以下未定义的行为:
bar.erase(bar.end());

为什么这不只是一个空操作?这是标准委员会的疏忽,将在语言的 future 修订版中解决,还是我没有看到重点的故意设计决定?

据我所知,它没有任何好处,但在执行以下操作时会造成额外的麻烦:
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 对一块内存进行 ojit_code 来覆盖已擦除的内存而无需分支,但这只会发生在特定场景中。

另请注意,与其他方式相比,从这里构建已检查的版本要容易得多:
checked_erase(Container cont, iterator it):
    if it != cont.end():
        cont.erase(it);

关于c++ - 删除最终迭代器是对标准的疏忽还是设计决策?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36681156/

10-16 02:13