已经回答得很好,但我将添加我的 S/0.02:执行此操作的“正确”方法是:
for (typename std::vector<MyObject>::size_type i = 0; i < object.size(); ++i) { ... }
只有有抱负的语言律师才会这样写,甚至他们也可能在读到好东西之前就停止阅读。
使用 C++11,您可以利用 decltype:
for (decltype(object.size()) i = 0; i < object.size(); ++i) { ... }
或者你可以利用auto:
for (auto i = object.size() - object.size(); i < object.size(); ++i) { ... }
或者你可以只使用size_t,但你仍然可能对溢出有疑问,因为vector<MyObject> 的size_type 可能大于size_t。 (不是,但不能保证):
for (size_t i = 0; i < object.size(); ++i) { ... }
那么,一个诚实的程序员应该做什么呢?
最简单的解决方案是 STL 从一开始就一直在推广的解决方案。除了一开始写起来也很痛苦:
for (typename std::vector<MyObject>::iterator_type it = object.begin(); it != object.end(); ++it) { ... }
现在,C++11 确实可以帮助您。你有一些非常好的选择,从简单的开始:
for (auto it = object.begin(); it != object.end(); ++it) { ... }
但它会变得更好(请打鼓)......:
for (auto& val : object) { ... }
这就是我要使用的那个。
编辑添加:
Cory Nelson 在评论中指出,还可以通过以下方式缓存 object.end() 的结果:
for (auto it = object.begin(), end = object.end(); it != end; ++it) { ... }
事实证明,for (var : object) 语法生成的代码与 Cory Nelson 提出的代码非常相似。 (所以我鼓励他和你只使用后者。)
但是,它的语义与其他语义略有不同,包括作为原始帖子主题的迭代。如果您在迭代期间以改变其大小的方式修改容器,那么您必须非常仔细地考虑问题。很有可能发生灾难。
迭代可能在迭代期间被修改的向量的唯一方法是使用整数索引,如原始帖子中所述。其他容器更宽容。您可以使用在每次迭代时调用 object.end() 的循环来迭代 STL 映射,并且(据我所知)即使面对插入和删除它也可以工作,但不要尝试使用 unordered_map,或向量。如果你总是在最后推并在前面弹出,它确实适用于双端队列,如果你在广度优先步行中使用双端队列作为队列,这很方便;我不确定你是否可以在后面弹出双端队列。
确实应该在某处简单总结容器类型的容器修改对迭代器和元素指针(并不总是与迭代器相同)的影响,因为这都是由标准指定的,但我从来没有在任何地方遇到它。如果你找到了,请告诉我。