为啥在 std::vector 擦除中需要 begin()?

Posted

技术标签:

【中文标题】为啥在 std::vector 擦除中需要 begin()?【英文标题】:why is begin() needed in std::vector erase?为什么在 std::vector 擦除中需要 begin()? 【发布时间】:2017-04-04 10:23:05 【问题描述】:

为什么一定要写v.erase(v.begin(), v.begin()+3)

为什么不将其定义为erase(int, int),这样您就可以编写v.erase(0,2) 并且实现会处理begin()s?

【问题讨论】:

因为整个 stl 都可以与迭代器一起使用,而且很方便,而且如果您以后想要将向量更改为列表,则无需更改代码,如果您使用迭代器,则 int 没有这样的运气. 【参考方案1】:

接口container.erase(iterator, iterator) 更通用,适用于没有索引的容器,例如std::list。如果您编写模板但并不确切知道代码要在哪个容器上工作,这是一个优势。

最初的设计旨在尽可能通用,迭代器比索引更通用。设计者本可以vector 添加额外的基于索引的重载,但决定不这样做。

【讨论】:

此外,迭代器可能来自<algorithm> 函数,并且具有那些返回索引将非常严格。【参考方案2】:

在 STL 中,迭代器是提供对 STL 容器的一般访问的唯一实体。

可以通过指针和索引访问数组数据结构。迭代器是这些索引/指针的泛化。 链表可以通过移动指针访问(比如ptr = ptr->next)。迭代器是对这些的泛化。 树和哈希表需要特殊的迭代器类来封装这些数据结构的迭代逻辑。

如您所见,迭代器是一种通用类型,它允许您对数据结构执行常见操作(例如迭代、删除等),而不管它们的底层实现。

这样,您可以重构代码以使用std::listcontainer.erase(it0, it1) 仍然可以在不修改代码的情况下工作。

【讨论】:

以上是关于为啥在 std::vector 擦除中需要 begin()?的主要内容,如果未能解决你的问题,请参考以下文章

std::vector.erase() 只擦除它应该擦除的一半

根据向量大小在 for 循环内擦除 std::vector 的索引

尝试擦除最后一个std :: vector元素时程序崩溃

在为每个执行一次时从 std::vector 中擦除?

从 std::vector 中删除多个对象?

为啥 C++ 不需要“new”语句来初始化 std::vector?