The compiler can optimize the second in the first, but it is assumed that these two are equivalent, i.e. end () is actually persistent. A slightly more problematic problem is that the compiler may not infer that the final iterator is constant due to possible overlap. However, assuming the end () call is inline, the difference is just loading memory.
Please note that this assumes that the optimizer is enabled. If the optimizer is not enabled, as is often done in debug builds, then the second formulation will include N-1 more function calls. In current versions of Visual C ++, debug builds will also be subject to extra hits due to checks on proog / epilog functions and heavier debug iterators. Therefore, in heavy STL code, by default in the first case, code execution in debug builds may be disproportionately slow.
Inserting and deleting inside a loop is an opportunity, as others have pointed out, but with this loop style, I find this unlikely. First, node containers β list, set, map β do not invalidate end () for any operation. Secondly, iterator increment often needs to be moved around in a loop to avoid invalidation problems:
// assuming list - cannot cache end () for vector
iterator it (c.begin ()), end (c.end ());
while (it! = end) {
if (should_remove (* it))
it = c.erase (it);
else
++ it;
} Thus, I am considering a loop that claims to call end () for mutate-in-loop reasons and still has ++ in the loop header to be suspicious.
Avery Lee Apr 28 '09 at 10:30 p.m. 2009-04-28 22:30
source share