Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

comparing iterators from different containers

Is it legal to compare iterators from different containers?

std::vector<int> foo;
std::vector<int> bar;

Does the expression foo.begin() == bar.begin() yield false or undefined behavior?

(I am writing a custom iterator and stumbled upon this question while implementing operator==.)

like image 357
fredoverflow Avatar asked Jan 11 '11 12:01

fredoverflow


2 Answers

If you consider the C++11 standard (n3337):

§ 24.2.1 — [iterator.requirements.general#6]

An iterator j is called reachable from an iterator i if and only if there is a finite sequence of applications of the expression ++i that makes i == j. If j is reachable from i, they refer to elements of the same sequence.

§ 24.2.5 — [forward.iterators#2]

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

Given that RandomAccessIterator must satisfy all requirements imposed by ForwardIterator, comparing iterators from different containers is undefined.

The LWG issue #446 talks specifically about this question, and the proposal was to add the following text to the standard (thanks to @Lightness Races in Orbit for bringing it to attention):

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.

like image 118
jweyrich Avatar answered Oct 06 '22 17:10

jweyrich


Undefined behavior as far as I know. In VS 2010 with

/*
* to disable iterator checking that complains that the iterators are incompatible (come from * different containers :-)
*/
#define _HAS_ITERATOR_DEBUGGING 0 

std::vector<int> vec1, vec2;

std::vector<int>::iterator it1 = vec1.begin();
std::vector<int>::iterator it2 = vec2.begin();

if (it1 == it2)
{
std::cout << "they are equal!!!"; 
}

The equality test returns in this case true :-), since the containers are empty and the _Ptr member of the iterators are both nullptr.

Who knows maybe your implementation does things differently and the test would return false :-).

EDIT:

See C++ Standard library Active Issues list "446. Iterator equality between different containers". Maybe someone can check the standard to see if the change was adopted?

Probably not since it is on the active issues list so Charles Bailey who also answered this is right it's unspecified behavior.

So I guess the behavior could differ (at least theoretically) between different implementations and this is only one problem.

The fact that with iterator debugging enabled in the STL implementation that comes with VS checks are in place for this exact case (iterators coming from different containers) singnals at least to me once more that doing such comparisons should be avoided whenever possible.

like image 22
ds27680 Avatar answered Oct 06 '22 18:10

ds27680