Search code examples
c++stliteratorcontainers

How should equality be defined for C++ iterators?


I'm implementing a directed graph data structure, where edges live in two simultaneous linked lists: The list of a vertex's outgoing edges, and the list of the opposite vertex's incoming edges.

I've defined iterators over incident edges, which traverse either list.

My question is this: How should I determine whether the iterators are equal? Should they compare equal iff they point to the same edge, or should they compare equal if they point to the same edge in the same list?

That is to say, should i == j imply that ++i == ++j and --i == --j (same position in the same traversal)? Or is it sufficient that &*i == &*j (reference the same object in memory)?

Which would be most consistent with the invariants/expectations for, say, STL iterators?


Solution

  • The standard's notion of a forward iterator, which is an iterator for a sequence that can be iterated over multiple times, requires that if i and j with i == j are dereferencable iterators (i.e. not one-past-the-end of value-initialized), then also i++ == j++.

    It also requires that i == j iff either both i and j are not dereferencable or both are dereferencable and *i and *j refer to the same object.

    However, in the standard the domain considered for == is that over a single sequence. All of the iterator properties always only apply over one specific sequence. Comparing iterators for different sequences generally has no specified behavior (i.e. UB in the standard library).

    Of course, nothing stops you from extending that concept to cover == between multiple sequences, but that's not going to be anything that standard library algorithms or other libraries using the standard's iterator concept are going to be able to make use of.

    In which way you extend =='s meaning is then up to you. That's going to depend on how you want to use the functionality.