aafoo
aafoo

Reputation: 33

comparing two end() iterators

list<int> foo;
list<int> foo2;
list<int>::iterator foo_end = foo.end();
list<int>::iterator foo2_end = foo2.end();

for (list<int>::iterator it = foo.begin(); it != foo2_end; ++foo) <- notice != comparison here
{
   ...

it this allowed? will it work correctly.

I am inclined to think that this is implementation dependent, anyone knows if standard says anything about this?

Upvotes: 3

Views: 905

Answers (3)

James McNellis
James McNellis

Reputation: 355207

There was a defect reported about this (LWG defect 446). The defect report asked whether it is valid to compare iterators that refer to elements of different containers.

Notes in the defect report explain that it was certainly the intention that doing so is undefined, but it is not explicitly stated that it is undefined.

The proposed resolution was to add the following to the standard, explicitly stating that it is undefined:

The result of directly or indirectly evaluating any comparison function or the binary - operator with two iterator values as arguments that were obtained from two different ranges r1 and r2 (including their past-the-end values) which are not subranges of one common range is undefined, unless explicitly described otherwise.

Edit: That language is not included in the C++0x FCD. This issue was in fact resolved by changes in N3066; specifically the following addition (§24.2.5/2):

The domain of == for forward iterators is that of iterators over the same underlying sequence.

Upvotes: 8

Artem Sokolov
Artem Sokolov

Reputation: 13701

It will compile but result in a seg fault. The iterators are object-specific, and comparing two iterators from different objects will always yield an inequality. So the it != foo2_end expression will always evaluate to true, and your program will crash when it reaches foo.end() and you attempt to dereference it.

Upvotes: 1

Peter Alexander
Peter Alexander

Reputation: 54290

Yes it is allowed (i.e. will compile).
No it will not work correctly.

foo2_end points to the end of foo2, not foo, so your iterator will start at the start of foo and end when it reaches the end of foo2, which will be never, because you are iterating foo. Once it iterates past the end of foo you will get a seg-fault.

Note: I assumed that you meant to write ++it, not ++foo.

Upvotes: 2

Related Questions