decrementing an iterator from begin

Does anyone know if the C++ language specification defines the behavior of a bi-directional iterator that is decremented to the position before begin()? Is the iterator necessarily valid so that it can be incremented back to the begin position? Or is the behavior left undefined?

Put another way, can one rely on the conditional below to be true for every possible STL container type x for any possible correct implementation of the STL?

1
2
3
4
5
i = x.begin();
--i;
++i;
if(i == x.begin())
    cout << "it works!" << endl;


It seems this works for sets and lists in gnu 4.4.3, but I'm really more interested in knowing if the behavior is defined in the standard.

Thanks,
Matt

(EDIT)

P.S. At the risk of sounding pedantic....

This is a yes or no question. It would be appreciated if answers begin with the word "yes" or "no". Good supplementary information would be the section of a C++ standards document that defines and explains the behavior. If you don't know the answer, it's not necessary to tell me my question delves into the obscure. I'm aware of that. Thanks.
Last edited on
It makes no sense to increment an iterator beyond end or decrement one before begin.

You may get away with it with a vector, but what would it mean for, say a, map or list?
No, the behavior of an iterator decremented before the begin position is not (I don't think) defined by the C++ language.

I was able to locate this answer myself. I found a downloadable copy of a draft version of c++11. Section 24.2.6 lists requirements for bidirectional iterators. Among them is the post-condition requirement of the decrement operation that (after a decrement) the iterator must be dereferenceable, which means (I think) that there is no requirement defining the behavior of an iterator decremented to the before-the-begin position.
> It seems this works for sets and lists
Implementing a list using a header node and making it circular, makes that after an increment or decrement you always reach a node.
That simplifies some operations, as you don't need to check for invalid pointer.
The same could apply to a map or a list.

The head node can't be dereference (as it does not have a `value' field), and could be used for the `end' iterator.
As a consequence a.end() not_eq b.end() and an iterator does not know if it is invalid
(by instance next == NULL
ne555,

Yes, I think I understand the advantages and ramifications of implementing containers with a header node (making them circular), but in any case, I was really only interested in whether you could count on such behavior within the framework of the requirements of the language. Apparently you can not.

Thanks,
Matt
Last edited on
Topic archived. No new replies allowed.