c++ for循环:条件的计算
C++ for loop: evaluation of condition
我有一个(傻吗?)关于循环的C/c++问题:
for (size_t i = 0; i < std::distance(begin, end); ++i) {
a.push_back(i);
}
begin
和end
是两个迭代器。我的问题是,std::distance(begin, end)
是否为循环中的每个元素计算?还是使用这个版本更好:
size_t dist = std::distance(begin, end);
for (size_t i = 0; i < dist; ++i) {
a.push_back(i);
}
第二个版本更好。在第一个中,每次都计算条件(没有自动假设结果是不变的)。
是。第二个版本更好。
对于第一个版本,如果容器类型a
为std::vector
, 和 begin
和end
是a
的迭代器,则push_back
操作可能会导致vector的大小调整,从而使begin
和end
迭代器失效,并且在下一次迭代中使用它们来计算距离将调用未定义行为。在这种情况下,第二种方法不仅更好,而且定义良好。
如果没有优化,它实际上每次都是计算的。在优化的实践中,它不应该有什么不同。如果它不是每次都计算(例如,因为这是你最内在的事情)是至关重要的,你总是可以保险起见,选择第二个。
这很可能取决于编译器的优化。如果它们被关闭,std::distance
将在每个循环中执行,这是肯定的。原因是迭代器可以在循环体内部被修改。
所以,如果你不改变迭代器,更喜欢第二个版本,即使它是非常小的优化。
在大多数情况下,这是一个个人选择的问题(如果这不是瓶颈,这是非常不可能的)。
EDIT
我的回答假设,您的代码中的begin
和end
是而不是向量(或无论它是什么)a
的begin
和end
。如果是,那么你的问题的答案取决于你实际想做什么。
编译器是否可以执行优化(至少)取决于所涉及的类型。例如,如果begin
和end
是列表迭代器,a
是列表,end
是a
末尾的迭代器,则这是一个无限循环(直到内存不足)。如果改变了程序的含义,编译器就不能进行"优化"。假定它不会改变程序的意义,否则您不会问这个问题,但是编译器仍然必须以某种方式排除这种可能性,例如通过跟踪end
的值从它设置的位置。在某些情况下,这对您来说可能是显而易见的,但超出了编译器的能力来证明。
相反,如果begin
和end
是向量迭代器,那么实际上它们要么是指针,要么是指针的薄包装。然后编译器可以很好地看到它们的值在循环中永远不会改变,因此它们的距离永远不会改变,并进行优化。即使它没有进行优化,distance
对于向量迭代器来说也是便宜的。因此,在这种情况下,优化可能并不那么重要。
与之相反,vector迭代器的检查实现在理论上可能包括检查自迭代器被获取后vector是否被重新分配(因此迭代器不再有效)的代码。这个事实可以在循环中更改,因此如果std::distance
间接调用该检查,那么在该实现中它不能被提升。并不是说你通常会把检查迭代器和优化结合起来,但这是可能的。
无论如何,对于第二个代码片段有些人更喜欢这种风格:
for (size_t i = 0, dist = std::distance(begin, end); i < dist; ++i) {
a.push_back(i);
}
它依赖于比较中的类型是相同的,但它避免将dist
放入周围的作用域,在那里它不需要。
两者都具有相同的性能,因为任何体面的编译器都会将代码转换为第二个版本。如果编译器优化被关闭,使用第二个版本
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 在循环条件 i<sqrtN(预先计算)和 i*i<N 中,C++哪个更有效?
- C++ 中的"if"语句不会从左到右计算条件
- 当我的 if 条件计算结果为 false 时,我的 else 块将不会执行
- 如何使用条件计算 3D 网格中从一个点到另一个点的所有路径
- 计算另一个图像像素满足条件的像素值的平均值
- 在C++中,是否可以编写一个条件的lambda,即只是一个计算结果为真或假的条件
- getline() 在 while 循环条件中如何计算为真或假?
- 如果满足嵌套条件,则计算结果未显示结果C
- 为什么这个条件运算符的计算结果为 int?
- 递归计算满足条件的值数并返回该数字
- 如果语句计算结果为 false,即使条件为真
- 计算文本文件中行数的最佳条件是什么
- 使用条件运算符递归计算模板化值或函数时出现错误 C1202(堆栈溢出)
- "if"条件的计算结果始终为 "true"
- 如果在循环条件下使用,将多次计算 strlen
- 条件断点:此表达式具有副作用,不会计算
- C++嵌套的条件运算符计算顺序
- 用于计算条件为真的实例的代码