Reading various questions here on Stack Overflow about C++ iterators and performance**, I started wondering if for(auto& elem : container)
gets "expanded" by the compiler into the best possible version? (Kind of like auto
, which the compiler infers into the right type right away and is therefore never slower and sometimes faster).
** For example, does it matter if you write
for(iterator it = container.begin(), eit = container.end(); it != eit; ++it)
or
for(iterator it = container.begin(); it != container.end(); ++it)
for non-invalidating containers?
The Standard is your friend, see [stmt.ranged]/1
For a range-based for statement of the form
for ( for-range-declaration : expression ) statement
let range-init be equivalent to the expression surrounded by parentheses
( expression )
and for a range-based for statement of the form
for ( for-range-declaration : braced-init-list ) statement
let range-init be equivalent to the braced-init-list. In each case, a range-based
for
statement is equivalent to{ auto && __range = range-init; for ( auto __begin = begin-expr, __end = end-expr; __begin != __end; ++__begin ) { for-range-declaration = *__begin; statement } }
So yes, the Standard guarantees that the best possible form is achieved.
And for a number of containers, such as vector
, it is undefined behavior to modify (insert/erase) them during this iteration.