向量和列表的end()迭代器的语义
semantics of end() iterator for vector and list
根据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运行到一个无限循环中。对我来说,解释似乎很简单:vector
的end()
迭代器指向一个内存位置,由于在基于范围的for循环中只对其求值一次,因此当它超过向量的第三个元素时就会停止。另一方面,list
可能有某种null标记作为结束迭代器,它总是放在最后一个元素之后,因此循环永远不会到达它
虽然结果看起来很简单,但我的问题是,标准对此有何规定?在每个标准库实现中都应该是这样吗,还是没有定义这种行为?在编写一个循环时,我应该期待什么,这个循环可能会将push_back()
调用到这样一个容器(无论如何,我通常都喜欢避免)?
我不认为这个标准很明确,但在一般来说,end
表示end
,如果在循环中的当前位置,你永远不会到达那里。
当然,使用vector
的第一个循环没有定义行为,因为insert(和erase)会使或超出插入位置,即使没有重新分配。并且结束迭代器将始终超出插入点。
相关文章:
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++中带有List类的迭代器Segfault
- 如何在c++迭代器类型中包装std::chrono
- 集合上的输出迭代器:assign和increment迭代器
- Boost Spirit,获取迭代器内部语义动作
- 对于set上的循环-获取next元素迭代器
- 为什么output_editor Concept不需要output_e迭代器标记
- c++17文件系统::recursive_directory迭代器()在mac上没有给出这样的目录,但在windows上
- 使用迭代器时如何访问对象在向量中的位置?
- std::vector::迭代器是否可以合法地作为指针
- 跟随整数索引列表的自定义类迭代器
- 不明白迭代器,引用和指针失效,一个例子
- 如何使用移动语义迭代器和模板
- boost::精神访问从语义操作定位迭代器
- 设置迭代器因移动语义失效
- 对输入迭代器语义/概念要求的混淆
- 向量和列表的end()迭代器的语义
- 重载迭代器:c++语义问题
- 语义迭代器声明