Variant a:
const auto end = whatever.end();
for (auto it = whatever.begin(); it != end; ++it)
{
// ...
}
Variant b:
const auto end = whatever.cend(); // note the call to cend insteand of end here
for (auto it = whatever.begin(); it != end; ++it)
{
// ...
}
Is there any reason to believe that variant b will be less efficient than variant a, since the loop condition compares two different kinds of iterators? Does this cause an implicit conversion on it
?
(end
is used multiple times inside the for loop, hence my desire to hoist it out.)
A const iterator points to an element of constant type which means the element which is being pointed to by a const_iterator can't be modified. Though we can still update the iterator (i.e., the iterator can be incremented or decremented but the element it points to can not be changed).
Const iterators are slightly faster, and can improve code readability. The default QSet::const_iterator constructor creates an uninitialized iterator.
However, as it is perfectly legal to 'delete' a const pointer in C++ (try it, it works!), it should be (and the behavior has been corrected in C++11) legal as well to 'erase" a const iterator from a container, provided the container itself is not const.
In principle, it could be less efficient and result in an implicit conversion with non-zero cost.
In practice, iterator
and const_iterator
are likely to participate in an inheritance relationship (either one derives from the other, or both derive from an _iterator_base
) such that the inequality operator is defined on the base class and there is no need for an implicit conversion (instead, the more-derived iterator gets ignored). Even in the absence of these, the conversion is likely to be trivial enough to be inlined and optimised out.
libstdc++ optimises these comparisons differently, by defining operator==
and operator!=
between iterator
and const_iterator
: http://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.3/a02037.html#l00295
libc++ doesn't have any optimisation: http://llvm.org/svn/llvm-project/libcxx/trunk/include/__tree - although again the constructor of const_iterator
from iterator
is so trivial that I'd expect it to be completely optimised out.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With