根据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运行到无限循环。对我来说,解释似乎很简单:end()
的{{1}}迭代器指向一个内存位置,而从it is only evaluated once during a range based for loop开始,它在到达向量的第3个元素时停止。另一方面,vector
可能有某种空标记作为结束迭代器,它总是放在最后一个元素之后,因此循环永远不会到达它。
虽然结果似乎很简单,但我的问题是标准对此有何看法?它是否应该在每个标准库实现中都是如此,或者这种行为是否未定义?在编写一个可能将list
调用到这样一个容器的循环时,我应该期待什么(我通常不想避免)?
答案 0 :(得分:5)
我不认为标准是非常明确的,但在
一般来说,end
表示end
,如果您插入元素,则表示vector
循环中的当前位置,你永远不会到达那里。
当然,您的第一个循环{{1}}未定义 行为,因为insert(和erase)使所有迭代器无效 或者超出插入位置,即使没有 再分配。而最终的迭代器将永远超越 插入点。