我们可以安全地依赖于迭代器的v.end()的位置吗?

时间:2014-03-06 18:01:53

标签: c++ vector stl iterator

对于STL中的向量v,存储v.end()(例如vector :: iterator)以供以后使用是否安全?我能保证当我以后使用存储的迭代器时,它仍然指向同一个位置吗?

考虑以下向量v
1, 2, 3, 4, 5

我现在将std::vector<int>::iterator it = v.end()存储起来。之后,我将2个新元素推入向量中,之后看起来像:
1, 2, 3, 4, 5, 6, 7

我现在可以放心*it == 6吗?

2 个答案:

答案 0 :(得分:6)

某些内容导入std::vector后,end()迭代器始终无效。

所有其他迭代器都有效,除非

  

新容器大小大于之前的容量


但是有些容器在推送后迭代器不会失效。请参阅this question的优秀答案。


如果您想要记住使用迭代器向量中的位置,而推送新元素,则可以确保新大小不超过旧容量使用reserve()成员。

std::vector<int> numbers = {1,2,3};
numbers.reserve(4);
int capacity = numbers.capacity();  // capacity >= 4
std::vector<int>::iterator pos = numbers.begin() + 2 // any iterator before
                                                     // the point of insertion
numbers.push_back(4); // new size is 4, old capacity is >= 4, 
                      // therefore pos is still valid. 

答案 1 :(得分:1)

§23.3.6.5/1[vector.modifiers]

  

如果新大小大于旧容量,则会导致重新分配。如果没有重新分配,   插入点之前的所有迭代器和引用都保持有效。

没有明确说明,但这意味着插入点处和之后的所有迭代器,引用都是无效的。这包括end迭代器。本节特别是关于insert / push_back,但在擦除等方面仍然或多或少都是准确的。

§23.3.6.3/5[vector.capacity]

  

重新分配使引用元素的所有引用,指针和迭代器无效   顺序。保证在插入之后不会发生重新分配   调用reserve()直到插入使向量的大小大于   capacity()的价值。