向量中的无效迭代器

时间:2017-04-19 16:43:18

标签: c++ vector iterator language-lawyer undefined-behavior

我知道擦​​除会在擦除点和擦除点之后使迭代器无效。考虑:

std::vector<int> vec = {1, 2, 3, 4, 5};
std::vector<int>::iterator it = vec.end() - 1; //last element
vec.erase(vec.begin()); //shift everything one to the left, 'it' should be the new 'end()' ?
std::cout << (it == vec.end()); //not dereferencing 'it', just comparing, UB ?

比较(而不是取消引用)无效的迭代器(在这种情况下为it)是不确定的行为?如果没有,it == vec.end()保证是否成立?

修改:如果只有it奇异值,则从顶部答案看起来这是UB。但是从What is singular and non-singular values in the context of STL iterators?开始,似乎it(或 )与容器关联,因此it 非单数

我很欣赏对此的进一步分析,谢谢。

2 个答案:

答案 0 :(得分:6)

一旦你的迭代器失效了,甚至可以将UB与其他东西进行比较:

  

[C++14: 24.2.1/10]: 无效的迭代器是一个可能是单数的迭代器。

     

[C++14: 24.2.1/5]: [..] 对于奇异值,大多数表达式的结果都是未定义的;唯一的例外是销毁一个包含奇异值的迭代器,一个非奇异值赋值给一个包含奇异值的迭代器,对于满足DefaultConstructible要求的迭代器,使用一个值初始化的迭代器作为复制或移动操作的来源。 [..]

请注意,这意味着您也无法将默认构造的迭代器与任何.end()进行比较。

与流行的观点相反,&#34;指针只是内存地址&#34;,这些规则对于指针来说也是如此。实际上,迭代器的规则是指针规则的概括。

答案 1 :(得分:1)

正式指向擦除元素上或之后的元素的任何迭代器都将失效。所以

  1. 是的,这是UB(尽管它是引擎盖下的指针。)

  2. UB,尽管有明显的合理性。