【发布时间】:2021-09-24 20:36:24
【问题描述】:
CLion linter 建议改变传统的 for 循环:
for (int i = 0; i < objects.size(); i++){
auto object = objects[i];
...
}
到基于范围的每个循环(c++11 起):
for (auto & object : objects) {
...
}
这个语法是否完全相同?我会争辩不,因为我至少在更复杂的程序中遇到了未定义的行为/崩溃。特别是在使用shared_ptr 的向量时。
为什么会发生这种情况?
【问题讨论】:
-
没有代码可以显示,谁能说?但是,这两个 for 循环并不完全相同。您的“手动”循环会创建一个副本,并且基于范围的 for 循环会引用每个元素。
-
for (int i = 0; i < objects.size(); i++)设置你有整数溢出,所以我会避免使用它。 -
您的两个示例不等效,因为一个通过引用获取
object,另一个通过值获取。否则,它们将是等价的,但如果您不需要索引,则基于范围的 for 循环在可读性方面会更好,而且它也不易出错。 -
如果您将第一个示例更改为使用
auto & object = objects[i];,则两者非常相似。在功能上存在一些细微的差异。在第一个版本中可以做一些在第二个版本中不能做的事情,比如在循环体中向objects添加元素。虽然如果您不需要做只有第一种形式允许的任何事情,第二种形式是首选。请注意,第一种形式仅适用于像std::vector这样的随机访问容器。例如,这种循环不适用于std::map或std::list。 -
把
auto object = objects[i];改成auto &object = objects[i];,或者把for (auto & object : objects)改成for (auto object : objects),那么在这种情况下,两个循环在功能上是相同的(假设循环体不需要i其他任何东西)。