9

根据 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 以vbeing结束{1,2,3,1,2,3},但代码 2 运行到无限循环。这个解释对我来说似乎很简单:指向内存位置的end()迭代器,并且由于它只在基于范围的 for 循环中被评估一次,所以当它到达向量的第三个元素时它会停止。另一方面,可能有某种空标记作为结束迭代器,它总是放在最后一个元素之后,因此循环永远不会到达它。vectorlist

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

4

1 回答 1

5

我认为该标准不是很明确,但总的来说,end意味着end,如果您在循环中插入超出当前位置的元素,您将永远无法到达那里。

当然,您的第一个循环 withvector具有未定义的行为,因为即使没有重新分配,插入(和擦除)也会使插入位置或插入位置之外的所有迭代器无效。并且结束迭代器将始终超出插入点。

于 2013-07-05T17:05:09.387 回答