我想知道为什么根据谓词从循环内的映射中进行擦除操作会使迭代器保持在valide状态,而不是为了向量
答案 0 :(得分:7)
Vector::erase
在删除的第一个元素之后使所有元素的迭代器无效。这是有道理的,因为向量将其数据存储在数组中。当一个元素被删除时,它之后的所有元素都需要移动,例如
int test[] = {0, 1, 2, 3, 4, 5};
^
在上面我们有一个迭代器指向我们想要的值5,但是,元素1被删除了,我们现在有:
0, 2, 3, 4, 5
^
迭代器指向数组的末尾,这是一个问题。
使用std::map
,数据存储在二叉树中,因此当删除元素时,某些节点的左/右指针会被修改,但它们在内存中的位置不会更改。因此,任何指向尚未擦除的元素的现有迭代器仍然有效。
答案 1 :(得分:4)
因为标准需要这种行为。
如果你想知道如何读取树(avl,rb)(也许从链接列表开始)
您可以通过思考从向量中间删除项目时发生的事情(即C样式数组;后续项目被移动),而不是从列表/树中删除(No项目被移动,只更新链接指针。
请注意,遍历可以使向量安全(通过使用序数索引而不是迭代器),但这不是重点:迭代器接口要求增量将导致下一个有效迭代器。对于向量而言,这不是真的(即使T *的'微不足道的'迭代器正在实现中使用)。
答案 2 :(得分:1)
请参阅http://www.sgi.com/tech/stl/Map.html
Map具有以下重要特性:将新元素插入到映射中不会使指向现有元素的迭代器无效。从地图中删除元素也不会使任何迭代器无效,当然,除了实际指向正在被删除的元素的迭代器之外。
它实际上是一个功能。 它不会使它们无效,因为它不必。对于矢量你必须这样做,因为至少擦除的那个元素的所有元素都会被移位并且指针会发生变化。