请考虑以下代码:
std::set<int> s;
auto it = s.begin();
s.insert(1);
s.insert(2);
std::cout << *it << std::endl;
输出(至少对我来说)是2
。这里发生了什么事?当我取消引用它时,it
的状态是什么?
我知道当我在空集上调用begin()
时,我会得到一个等价于end()
的迭代器。我也知道在insert
上调用set
并不会使其迭代器失效。即使我现在已经将元素插入到end()
中,迭代器也会以某种方式保持等效于set
,所以现在我得到了未定义的行为?这是由标准定义的吗?
答案 0 :(得分:7)
当你在这里调用s.begin()
时,它会返回一个结束迭代器,因为容器是空的。插入符号不会使此迭代器失效:每次插入后,此迭代器仍然是结束迭代器。
取消引用此迭代器会导致程序显示未定义的行为(无法取消引用结束迭代器)。
答案 1 :(得分:1)
迭代器it
仍然等于s.end()
。取消引用结束迭代器是未定义的行为。这就是你所看到的。试试这个例子
if (it == s.end())
{
cout << "at end\n";
}
这是合法代码。
答案 2 :(得分:0)
“it”在第一种情况下指向s.end(),它是fantom元素的地址。 fantom元素的地址只是容器中最后一个元素之后的“不存在”元素的地址。修改集后,插入前最初指向s.end()的“it”可能与插入后的s.end()不同。
因此,取消引用“它”会导致未定义的行为。