我知道擦除会在擦除点和擦除点之后使迭代器无效。考虑:
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
非单数。
我很欣赏对此的进一步分析,谢谢。
答案 0 :(得分:6)
一旦你的迭代器失效了,甚至可以将UB与其他东西进行比较:
[C++14: 24.2.1/10]:
无效的迭代器是一个可能是单数的迭代器。
[C++14: 24.2.1/5]:
[..] 对于奇异值,大多数表达式的结果都是未定义的;唯一的例外是销毁一个包含奇异值的迭代器,一个非奇异值赋值给一个包含奇异值的迭代器,对于满足DefaultConstructible
要求的迭代器,使用一个值初始化的迭代器作为复制或移动操作的来源。 [..]
请注意,这意味着您也无法将默认构造的迭代器与任何.end()
进行比较。
与流行的观点相反,&#34;指针只是内存地址&#34;,这些规则对于指针来说也是如此。实际上,迭代器的规则是指针规则的概括。
答案 1 :(得分:1)
正式指向擦除元素上或之后的元素的任何迭代器都将失效。所以
是的,这是UB(尽管它是引擎盖下的指针。)
UB,尽管有明显的合理性。