向量和列表的end()迭代器的语义

semantics of end() iterator for vector and list

本文关键字:迭代器 语义 end 列表 向量      更新时间:2023-10-16

根据C++标准,如果向量的新大小超过其容量,则在向量上调用push_back()会使迭代器无效,但在列表中,它从不使迭代程序无效。现在考虑以下代码片段:

1.

vector<int> v{1,2,3};
v.reserve(100);
for (int i: v) {
    v.push_back(i);
}

2.

list<int> l{1,2,3};
for (int i: l) {
    l.push_back(i);
}

我在gcc 4.8中尝试过,发现代码1以v{1,2,3,1,2,3}结束,但代码2运行到一个无限循环中。对我来说,解释似乎很简单:vectorend()迭代器指向一个内存位置,由于在基于范围的for循环中只对其求值一次,因此当它超过向量的第三个元素时就会停止。另一方面,list可能有某种null标记作为结束迭代器,它总是放在最后一个元素之后,因此循环永远不会到达它

虽然结果看起来很简单,但我的问题是,标准对此有何规定?在每个标准库实现中都应该是这样吗,还是没有定义这种行为?在编写一个循环时,我应该期待什么,这个循环可能会将push_back()调用到这样一个容器(无论如何,我通常都喜欢避免)?

我不认为这个标准很明确,但在一般来说,end表示end,如果在循环中的当前位置,你永远不会到达那里。

当然,使用vector的第一个循环没有定义行为,因为insert(和erase)会使或超出插入位置,即使没有重新分配。并且结束迭代器将始终超出插入点。