C++容器的迭代器失效规则是什么?
优选地以摘要列表格式.
(注意:这是Stack Overflow的C++常见问题解答的一个条目.如果你想批评在这种形式下提供常见问题解答的想法,那么发布所有这些的元数据的发布将是这样做的地方.这个问题在C++聊天室中受到监控,其中FAQ的想法一开始就出现了,所以你的答案很可能被那些提出想法的人阅读.)
关于迭代器失效规则的这个问题,很明显标准的精神意味着,例如"deque中间的擦除使所有迭代器无效并且对deque元素的引用"也指最终迭代器.
但是,我无法找到标准使其明确的任何地方,严格来说,结束迭代器不是容器中元素的迭代器.
2003年的标准是否明确了这一点?
我发现这个C++代码:
vector<int> a;
a.push_back(1);
a.push_back(2);
vector<int>::iterator it = a.begin();
a.push_back(4);
cout << *it;
Run Code Online (Sandbox Code Playgroud)
打印一些大的随机数; 但如果你a.push_back(3)在第3行和第4行之间添加,它将打印1.你能解释一下吗?
一般来说,为了效率和速度目的,缓存一个结束迭代器(特别是STL容器)是个好主意吗?比如在下面的代码中:
std::vector<int> vint;
const std::vector<int>::const_iterator end = vint.end();
std::vector<int>::iterator it = vint.begin();
while (it != end)
{
....
++it;
}
Run Code Online (Sandbox Code Playgroud)
在什么条件下最终价值会失效?从容器中擦除会导致所有 STL容器中的结尾无效还是只有一些?
这更像是一个设计问题,即(在STL或其他地方)是否有像过去的迭代器"重新验证"这样的概念?
我的意思和用例:假设一个算法需要"尾随"一个容器(如队列).它遍历容器直到end()到达,然后暂停; 独立于此,程序的另一部分将队列中的更多项目排入队列.算法(EDIT)如何有效地告诉"有更多的项目已经入队",同时保持以前的过去的迭代器(称之为tailIt)?(这意味着它能够检查是否tailIt == container.end() 仍然,如果这是假的,则conclude tailIt现在有效并指向插入的第一个元素).
请不要将这个问题视为"不,没有" - 我正在寻求围绕如何以惯用的方式设计一些逻辑的判断,并且有很多选择(事实上,所讨论的迭代器是一只手- 我可以提供此属性的构建数据结构- 结束()重新验证 - 但我想判断它是否是一个好主意).
编辑:明确我们有迭代器tailIt 和引用container.我正在尝试做的一个简单的解决方法是,还要记住count:=您处理了多少项,然后检查container.size() == count仍然是,如果没有,请container[count]从那里寻求并继续处理.这带来了许多缺点(额外状态,假设容器不从前面弹出(!),随机访问以进行有效搜索).
我需要一种快速访问容器中数据的方法.
所以我记得那个数据位置的迭代器.之后可以修改容器(添加和删除元素),但如果我使用的容器类型不会使我的迭代器失效(比如std::map或std::list),我很好.
此外,我的数据可能不在容器中(还),所以我设置了一个迭代器container.end()来反映它.
哪个标准容器保证end()在添加和删除元素时不会改变?所以我仍然可以将我的迭代器与返回的值进行比较,container.end()而不是得到假阴性.
c++ ×6
iterator ×5
containers ×2
stl ×2
algorithm ×1
c++-faq ×1
c++11 ×1
c++17 ×1
invalidation ×1
vector ×1