The first one is faster because end()
isn't called on every iteration. And no, the optimizer can't easily cache that for you, because it doesn't know whether the size of the container has changed in this iteration (and hence the end moved). This also applies to a const container due to the aliasing problem.
i++
returns a copy of i, then increments. ++i
increments, then returns the incremented value. Hence, when you are discarding the return value, use ++i
because it needs to do less work (no copying). The optimizer is quite likely to fix an inlined i++
call so it's as fast as ++i
but don't rely on that.
Me? I use
for(int i = 0; i < m.size(); i++) {
// ... do something with m[i]
}
Because it's the shortest and most clear. Why int
and not MyClass::size_type
? Because it's simpler and I have never had to worry about the edge cases so far. Why i++
? Because for basic types it's always optimized into ++i
, and it's less confusing for coworkers. As a bonus, I can use i
as a numeric value as well. With an iterator, I'd have to keep a separate counter, or use std::distance
.
obecalp points out that this doesn't work with half of the standard containers, like list
and map
. Indeed those require using a proper iterator. Relatedly, you should always use an iterator
when writing generic code.