tags:

views:

98

answers:

3

Good Day,

Assume that I am writing a Python-like range in C++. It provides all the characteristics of Random Access containers(Immutable of course). A question is raised in my mind about the following situation:

I have two different iterators, that point to different instances of the range container. The thing is that these two ranges are equal. i.e. they represent the same range. Would you allow the following situation:

fact: range1 == range2 e.g.
---------------------------
range range1(10, 20, 1), range2((10, 20, 1);
range::iterator i = range1.begin(), j = range2.begin();
assert(i == j); // would you allow this?

Sorry if I am missing a simple design rule in STL :)

+3  A: 

By default, in the STL, two iterators from two different container are not comparable. This means, the behavior is unspecified. So you do whatever you want, nobody should even try.

edit

After looking carefully at the standard, section 24.1, paragraph 6 states:

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 the same container.

Which means that if you allow i == j with i and j in two different container, you really consider both container as being the same. As they are immutable, this is perfectly fine. Just a question of semantic.

PierreBdR
Thanks. This is the first time I know about this :) Do you know where can I find that in the standard?
AraK
I would add that, were you using strings, and if the implementation performed an intern operation on all strings, comparing two == strings may result in teh same behavior. It's not required, but it might happen. I would not worry if it does happen, but I would not require it to happen either.
KitsuneYMG
VC at least complains when you try to compare iterators that point to different containers. Do you know if the standard says it's illegal to compare them? Or is VC just being overly helpful? Paragraph 7 of 24.1 looks to be the closest to saying now, but it's actually describing "ranges" and "algorithms". The question is, is it valid to compare 'i == j' even though they don't point to the same container?
Richard Corden
A: 

In STL the comparison rules are driven by the container's elements and not the container itself, so in my opinion you shouldn't be performing the dereference your self in your == operator overload.

Naveed
+1  A: 

You might want to check boost::counting_iterator. Combined with boost::iterator_range you'll get something analogous to your range class (except that it will only allow a step-size of 1):

auto rng = boost::make_iterator_range(boost::make_counting_iterator(0),
                                      boost::make_counting_iterator(10));
for(auto it = rng.begin(), e = rng.end(); it != e; ++it)
    std::cout << it << " "; // Prints 0,1,2,3,...,9

For this class two iterators are considered equal provided that they contain the same number. But admittedly the situation is different than yours because here each iterator doesn't know to which range it belongs.

Manuel