哪个更好?
for (auto anItem = aVector.begin(), endVector = aVector.end(); anItem != endVector ; ++anItem )
或者
for (auto anItem = aVector.begin(), anItem != aVector.end(); ++anItem )
我总是使用第二个 - 更简单的一个。
我相信您期望 first 会更快,但是 std::vector::end() 的典型实现是返回指向 vector 中最后一个元素之后的第一个元素的简单指针,因此实际上在第二种情况下没有性能改进,因为end() 始终是内联函数。当您像这样存储当前 end() 时,可能会提高性能const iterator
:
const decltype(aVector.end()) endVector = aVector.end();
for (auto anItem = aVector.begin(); anItem != endVector ; ++anItem )
但是在许多情况下,这个循环和你的第一个循环不如你的第二个循环安全。这就是为什么我几乎总是看到第二个循环。
[更新]
在谈论性能时,我不认为第一个循环比第二个循环有任何优势。现代编译器可以检测到 aVector.end() 结果在整个循环中没有变化,因此它们可以自由优化。第一个循环的唯一性能优势可能是 aVector 在循环中发生变化的情况 - 但这会导致错误的行为。
所以,从任何方面来看这个问题——第二个循环总是更好。
[更新2]
只是为了检查它。我写了两个这样的函数:
int test1(std::vector<int>& a)
{
int retVal = 0;
for (std::vector<int>::iterator it = a.begin(), aend = a.end(); it != aend; ++it)
{
retVal += *it;
}
return retVal;
}
int test2(std::vector<int>& a)
{
int retVal = 0;
for (std::vector<int>::iterator it = a.begin(); it != a.end(); ++it)
{
retVal += *it;
}
return retVal;
}
并将它们编译为 assembler g++ -O3 -S
。我的计算机/编译器上的汇编代码没有区别 - 但这并不意味着它们在所有情况下都没有任何区别。
第二个更好,那是因为所有(是的,100%)程序员都使用它。(假设你没有在迭代中擦除任何东西,在这种情况下for
循环不是最好的选择)