2
votes

In something like an std::vector the ::end() iterator will point to one past the last element. You can't dereference this iterator but you can compare it to another iterator. If you compare another iterator to end() you know you've reached the end of the container. In the case of containers that aren't arrays, such as a tree or linked list, what values do these end iterators have to compare other iterators with?

1
That's implementaiton defined, specify a particular compiler please.πάντα ῥεῖ
The natural way to implement this would be a sentinel representing an empty value BTW.πάντα ῥεῖ
@πάνταῥεῖ — it’s not implementation defined. It’s implementation specific. Implementation defined means that the implementation is required to document its behavior.Pete Becker
@PeteBecker Well, sorry. It's compiler specific though.πάντα ῥεῖ
@πάνταῥεῖ Only insofar as the compiler sets the standard library. Which might be overridable. libc++/libstdc++ anyone?Deduplicator

1 Answers

4
votes

The C++ standard defines the ending iterator value in an axiomatic fashion:

22.2.1 General container requirements [container.requirements.general]

...

begin() returns an iterator referring to the first element in the container. end() returns an iterator which is the past-the-end value for the container. If the container is empty, then begin() == end().

"Past-the-end" is your only, axiomatic, definition to work with. That's all you get. Each C++ implementation is free to implement the ending iterator value in any fashion that meets this, and other related requirements. Just as an example: one possibility would be to use a null pointer for the ending iterator value (provided that all other requirements are also met, i.e. the decrement operation produces an iterator to the last element in the (non-empty) container, and incrementing the iterator to the last element produces this implementation null pointer.

That, of course, is not the only possible implementation, but whatever the actual implementation of your C++ compiler -- that's generally irrelevant to any well-formed C++ code. The well-formed C++ code is not going to compare a particular iterator to a null pointer, explicitly, to check for the ending iterator value, it will compare it with whatever end() returns.