Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are comparisons between iterator and const_iterator inefficient?

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.)

like image 539
fredoverflow Avatar asked Jul 06 '12 13:07

fredoverflow


People also ask

What is the difference between iterator and Const_iterator?

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).

Are Const iterators faster?

Const iterators are slightly faster, and can improve code readability. The default QSet::const_iterator constructor creates an uninitialized iterator.

Can you erase a const 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.


1 Answers

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.

like image 150
ecatmur Avatar answered Sep 28 '22 11:09

ecatmur