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

时间:2013-07-05 16:42:09

标签: c++ c++11 iterator

根据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调用到这样一个容器的循环时,我应该期待什么(我通常不想避免)?

1 个答案:

答案 0 :(得分:5)

我不认为标准是非常明确的,但在 一般来说,end表示end,如果您插入元素,则表示vector 循环中的当前位置,你永远不会到达那里。

当然,您的第一个循环{{1}}未定义 行为,因为insert(和erase)使所有迭代器无效 或者超出插入位置,即使没有 再分配。而最终的迭代器将永远超越 插入点。