Search code examples
c++iteratorconst-iterator

Should conversions from non-const iterator to const iterator be avoided?


I was attempting to compare a const iterator to a non-const iterator but was not certain whether it was okay, so I looked it up. I found out it is OK due to an implicit conversion of non-const iterator to const iterator. However, I was wondering whether you should prefer to not compare these iterators, in order to avoid this conversion. For example,

begin_iterator = buf.begin();  end_iterator = buf.cend();
for (; begin_iterator != end_iterator; ++begin_iterator) { ... }

Regularly, I would consider this OK as const means read-only, which is fine. However, I am uncertain about the (unnecessary) conversion.


Solution

  • While this might work in this case, it's not the standard pattern for creating ranges. In particular, the standard algorithms expect two iterators of the same type, so, for example, std::fill(whatever.begin(), whatever.cend(), 3) would not compile.

    As a result, the code in the question creates a maintenance problem. Suppose a maintainer realizes that the for loop is doing something that can be done with a standard algorithm. The obvious transformation is to replace the for loop with the algorithm. So

    begin_iterator = buf.begin();  end_iterator = buf.cend();
    for (; begin_iterator != end_iterator; ++begin_iterator) { ... }
    

    becomes

    begin_iterator = buf.begin();  end_iterator = buf.cend();
    std::whatever(begin_iterator, end_iterator);
    

    but that doesn't compile, so the maintainer has to hunt around and discover that the two iterators are not the same type, and then figure out whether it's okay to change the type of the end iterator to match the begin iterator. That means examining all of the places where the end iterator is used, to determine why it's a different type and whether that matters.

    So the real issue is, what problem does this solve, and is the cost worth it? In general, the answer to the first is "nothing important" and the answer to the second is "no".