
Dear Robert, [ We're probably in danger of irritating other people if we continue this discussion too long let's try and keep it brief].
My second gripe is that even the idea of undefined behaviour is inconsistent (in MSVC at least). I can quite happily iterate something to .end() (one past the last element) but not to .end()+n --- why?
Because dereferencing an end iterator has undefined behavior.
The above was a slip of the finger. I agree with you regarding the .end() + n. I should have based it on .begin() which was the original source of my iteration. A concrete example of what I'm talking about is here: http://tinyurl.com/ns8j83 I assert that the problem is that the bounds checking in MSVC is wrong - it should only be checking for the de-referencing of invalid iterators not their creation. What do you think?
From what I can see this prevents the simple creation of a striding iterator, for which the .end() can be at .end() + stride of the underlying vector. One can do it easily by default in g++ as it doesn't hold your hand (exposing you to dereferincing this as being undefined) and leaving that up to you. In MSVC8 it will barf since the debug bounds checking doesn't allow you to keep iterating past the end.
The debug bounds checking is revealing that you are relying on undefined behavior.
I may be in practice - but I don't think I am in principle.
Which is the correct treatment?
Perhaps you're unfamiliar with the phrase "undefined behavior."
It's occasionally been used to describe the conduct of some friends of mine.
If it isn't clear by now, don't dereference an end iterator and don't try to dereference anything past it.
I don't think I am -- that's my point. Ultimately are random access iterators *supposed* to be homeomorphic to the integers in the same (apparent) way C indices are? -ed