Why using != to compare iterator in loop condition

In many examples regarding iterating over vectors, I noticed that often the not-equals operator is used to check whether the loop has reached the vector’s end. Normally, I am using the lower-than operator in the loop condition. Hence, I am wondering, what is the rationale behind choosing !=?

Example:

std::vector<int> vec = {1, 2, 3, 4, 5};
for (auto iter = vec.begin(); iter != vec.end(); iter++) {
  std::cout << *iter << " ";
}

Answer

Because not all iterators support ordering but all can be compared for equality in O(1).

For example associative (ordered) containers use bidirectional iterators, which are defined as (cppreference):

template<class I>
  concept bidirectional_iterator =
    std::forward_iterator<I> &&
    std::derived_from</*ITER_CONCEPT*/<I>, std::bidirectional_iterator_tag> &&
    requires(I i) {
      { --i } -> std::same_as<I&>;
      { i-- } -> std::same_as<I>;
    };

std::forward_iterator can only be dereferenced, copied, ==, and incremented.

On the other hand, random access iterator used by std::vector requires std::totally_ordered<I>. So in your case you could write iter < vec.end();, but the code will become less generic. As long as you do not increment the iterator in the loop’s body, you are safe anyway.