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.)
In principle, it could be less efficient and result in an implicit conversion with non-zero cost.
In practice,
iteratorandconst_iteratorare 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==andoperator!=betweeniteratorandconst_iterator: http://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.3/a02037.html#l00295libc++ doesn’t have any optimisation: http://llvm.org/svn/llvm-project/libcxx/trunk/include/__tree – although again the constructor of
const_iteratorfromiteratoris so trivial that I’d expect it to be completely optimised out.