【发布时间】:2012-11-16 21:32:22
【问题描述】:
考虑以下代码:
std::set<int> s;
auto it = s.begin();
s.insert(1);
s.insert(2);
std::cout << *it << std::endl;
输出(至少对我而言)是2。这里发生了什么事?当我取消引用 it 时,它的状态是什么?
我知道当我在一个空集上调用begin() 时,我得到一个等效于end() 的迭代器。我也知道在set 上调用insert 不会使其迭代器无效。即使我现在已经将元素插入到 set 中,迭代器是否以某种方式保持等同于 end() ,所以现在我得到了未定义的行为?这是标准定义的吗?
【问题讨论】:
-
我相信如果您更改容器,迭代器就会失效。所以这是UB。
-
@ahenderson 不正确,您可能正在考虑向量。
-
根据this,迭代器没有失效。
-
@Xymotech:这实际上是一个极端案例。该标准仅保证引用容器中元素的迭代器不会失效。情况并非如此,因为当调用
begin()函数时容器是空的,因此迭代器确实 not 引用容器中的元素。标准中没有关于容器的end()迭代器的保证。 -
@JamesMcNellis:在与 Alisdair 重新讨论后,他的立场是措辞不够精确,但没有保证。特别是
end()迭代器在插入时可能无效的极端情况是在一些实现中,这些实现具有动态分配的哨兵,第一个元素插入到容器中。在这些实现中,在空容器上end()是一个带有空指针的迭代器,但在第一次插入之后end()是一个带有指向哨兵对象的指针的迭代器。
标签: c++ iterator set containers