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

pet*_*ohn 9 c++ iterator c++11

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

1.

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

2.

list<int> l{1,2,3};
for (int i: l) {
    l.push_back(i);
}
Run Code Online (Sandbox Code Playgroud)

我用gcc 4.8尝试过了,发现代码1点结束与v{1,2,3,1,2,3},但代码2个运行进入无限循环.对我来说,解释似乎很简单:指向内存位置的end()迭代器vector,并且因为它仅在基于循环的范围内计算一次,所以当它到达向量的第3个元素时它会停止.另一方面,list可能有一些null标记作为结束迭代器,它总是放在最后一个元素之后,因此循环永远不会到达它.

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

Jam*_*nze 5

我不认为标准是非常明确的,但一般来说,end意味着end,如果你在循环中插入超出当前位置的元素,你将永远不会到达那里.

当然,你的第一个循环vector具有未定义的行为,因为即使没有重新分配,insert(和erase)也会使插入位置或超出插入位置的所有迭代器无效.最后的迭代器总是超出插入点.

  • @AndreyT和@James Kanze:`std :: vector :: push_back`的cppreference文档现在应该更好了. (2认同)