为什么 C++ 在使用容器时不会使 begin() 无效
Why C++ doesn't invalidate begin() when using containers
据我了解,使用容器的 insert() 或 erase() 方法会使容器无效,因此最好不要在执行 insert() 或 erase() 操作之前使用迭代器缓存容器的末尾,我很困惑为什么只有容器的最后一个位置无效而不是第一个位置。 (书中没有建议我们不应该缓存引用容器的 begin() 的迭代器)。
这似乎是一个愚蠢的问题,但 "invalidate" 不意味着容器中元素的地址完全改变了吗?我们如何确保容器的起始地址始终保持不变?
每个容器都有自己的规范,说明哪些操作会使哪些迭代器无效。规范基于预期的实施。
例如,向量上的 erase()
只会使经过新末端的迭代器无效,因为 erase()
所做的只是销毁新末端以外的对象并更新向量的大小:这意味着新结束之前的对象不会被销毁,它们保留在相同的内存位置,因此指向这些对象的迭代器和指针保持不变。
另一方面,如果新的 size()
大于当前的 capacity()
,向量上的 insert()
将导致重新分配内部缓冲区,这意味着所有对象可能会被移动,因此向量中的所有迭代器和指针都将失效,包括 begin()
.
据我了解,使用容器的 insert() 或 erase() 方法会使容器无效,因此最好不要在执行 insert() 或 erase() 操作之前使用迭代器缓存容器的末尾,我很困惑为什么只有容器的最后一个位置无效而不是第一个位置。 (书中没有建议我们不应该缓存引用容器的 begin() 的迭代器)。
这似乎是一个愚蠢的问题,但 "invalidate" 不意味着容器中元素的地址完全改变了吗?我们如何确保容器的起始地址始终保持不变?
每个容器都有自己的规范,说明哪些操作会使哪些迭代器无效。规范基于预期的实施。
例如,向量上的 erase()
只会使经过新末端的迭代器无效,因为 erase()
所做的只是销毁新末端以外的对象并更新向量的大小:这意味着新结束之前的对象不会被销毁,它们保留在相同的内存位置,因此指向这些对象的迭代器和指针保持不变。
另一方面,如果新的 size()
大于当前的 capacity()
,向量上的 insert()
将导致重新分配内部缓冲区,这意味着所有对象可能会被移动,因此向量中的所有迭代器和指针都将失效,包括 begin()
.