Reputation: 438
I'm currently updating some older C++ code that I have that iterates over STL container types, and I'm finding a lot of code like this:
if (!edgeSet.empty())
{
for(typename EdgeSet::const_iterator iter = edgeSet.begin(); iter != edgeSet.end(); iter++)
{
...
}
}
Which I am turning (successfully) into the equivalent:
if (!edgeSet.empty())
{
for(auto& edge : edgeSet)
{
...
}
}
And I was wondering... is the "empty
" check necessary for a "range for"? I would imagine it would be necessary in the older "iterator style" for loop to avoid a useless initialization and comparison / branch, but I'm curious if a "range for" automatically does an empty check or not before it even starts.
Further, if the optimization does happen, does it happen at all optimization levels (including no optimization: -O0
)?
Thanks in advance.
Upvotes: 0
Views: 2541
Reputation: 26800
The empty()
function checks if the container has no elements, i.e. whether begin() == end()
and returns true
if container is empty.
The range-based for
loop produces code equivalent to the following
{
auto && __range = range_expression ;
for (auto __begin = begin_expr, __end = end_expr;
__begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
The controlling expression in the for
loop is is __begin != __end
.
You can see the check in empty()
and the check here are equivalent.
So there is no need for an additional empty()
check before using the range-based for
loop.
Upvotes: 3