3

考虑以下代码:

std::set<int> s;
auto it = s.begin();
s.insert(1);
s.insert(2);
std::cout << *it << std::endl;

输出(至少对我而言)是2. 这里发生了什么事?it我取消引用它时的状态是什么?

我知道当我调用begin()一个空集时,我得到一个等效于end(). 我也知道调用insertaset不会使其迭代器无效。end()即使我现在已将元素插入到中,迭代器是否以某种方式保持等效set,所以现在我得到了未定义的行为?这是标准定义的吗?

4

3 回答 3

7

当你s.begin()在这里调用时,它返回一个结束迭代器,因为容器是空的。此迭代器不会因插入而失效:每次插入后,此迭代器仍是结束迭代器。

取消引用此迭代器会导致您的程序表现出未定义的行为(无法取消引用结束迭代器)。

于 2012-11-16T21:37:02.617 回答
1

迭代器it仍然等于s.end()。取消引用结束迭代器是未定义的行为。这就是你所看到的。试试这个例如

if (it == s.end())
{
    cout << "at end\n";
}

这是法律代码。

于 2012-11-16T21:37:43.737 回答
0

第一种情况下的“it”指向 s.end(),它是 fantom 元素的地址。fantom 元素的地址只不过是容器中最后一个元素之后的“不存在”元素的地址。一旦修改了集合,在插入之前最初指向 s.end() 的“it”可能与插入之后的 s.end() 不同。

因此,取消引用“它”会导致未定义的行为。

于 2012-11-16T21:45:28.683 回答