I'm struggling to understand implementation requirements for the end() function which returns an iterator pointing one past the last element. What does one past last element mean? Isn't it always going to be null? And if it holds no information then how can I get to the final node of BST with O(1) time complexity with the help of end()?
1 Answer
The concept of a "null" element etc. is something that simply doesn't figure in the iterator semantics. It's literally meaningless. Iterators aren't raw C pointers.
It's on you to design your iterators such that end()-1 on a non-empty container returns the final node, if the iterator is bidirectional to start with.
For the more general case of a forward iterator, all that you really wish is that some iterator equals end() when it's been incremented one past the last element, or begin() == end() when there are no elements.
This is sometimes done by having end() point to a special node that only exists to facilitate end()'s functionality.
An iterator could store a boolean field indicating whether it's the result of end(), for example. Iterators can hold as much information as you desire. It's an optimization to lower that amount, but an optional one.
Nobody forces you, of course, for begin() and end() to be the only available means of obtaining an iterator.
std::set?