1. Originally Posted by robatino
The only problem is that it needs to be initialized to some special value so it can be determined whether it changed, and with iterators any valid value must be associated with a specific container. One workaround would be to define a dummy container c of zero size, and set it to c.end().
If x is an iterator, then it is always true that x == x, no matter what particular value the iterator has. Also, if x is not a valid iterator and y is, then it is always true that x != y. Which container the iterators came from doesn't enter into the logic.

2. > Also, if x is not a valid iterator and y is, then it is always true that x != y.

I'm fairly sure that unless x and y are both valid iterators to the same container, comparing x and y for equality will be undefined behavior. Can someone confirm or refute this?

Edit: As a corollary, I suspect that if x is an invalid iterator - say, if it hasn't been initialized - then the following is also false:

> If x is an iterator, then it is always true that x == x, no matter what particular value the iterator has.

3. If x is not a valid iterator, i.e. x has the so-called singular value, then absolutely every operation except for assignment and destruction will invoke undefined behaviour. It is not true that x != y for any valid y, because the comparison invokes undefined behaviour. It is not true that x == x, because the comparison invokes undefined behaviour.

To do anything with an iterator at all, it needs to have a valid value.

24.1/5 says:
Iterators can also have singular values that are not associated with any container. [...] Results of most expressions are undefined for singular values; the only exception is an assignment of a non-singular value to an iterator that holds a singular value. In this case the singular value is overwritten the same way as any other value. Dereferenceable and past-the-end values are always non-singular.
I believe a later defect report clarified that destruction is a valid operation on a singular iterator.

4. What about comparing two valid iterators to different containers? I believe it's undefined behavior but want to be sure, since I'm implementing a custom iterator for a container and am currently assuming that it's not necessary to worry about comparing iterators to two different instances of the container.

5. Originally Posted by CornedBee
If x is not a valid iterator, i.e. x has the so-called singular value, then absolutely every operation except for assignment and destruction will invoke undefined behaviour. It is not true that x != y for any valid y, because the comparison invokes undefined behaviour. It is not true that x == x, because the comparison invokes undefined behaviour.
I don't doubt you on this one. But it's a bunch of crap. If all such operations on invalid iterators are undefined, then there should have been no public default constructor for those iterators.

The expression x == x should always be true, regardless of what x is, in my opinion.

6. What about comparing two valid iterators to different containers?
Undefined for relational operations (or pointers wouldn't be iterators). I believe it's iterator-dependent for equality. The standard doesn't say.

But it's a bunch of crap. If all such operations on invalid iterators are undefined, then there should have been no public default constructor for those iterators.
Sorry, that's nonsense. There are important use cases for having an iterator temporarily be a singular value, to have a default-constructible iterator.

The expression x == x should always be true, regardless of what x is, in my opinion.
It's not like the expression yields false. It simply is undefined. You can't do it.

7. > Undefined for relational operations (or pointers wouldn't be iterators). I believe it's iterator-dependent for
> equality. The standard doesn't say.

But aren't == and != relational operators (in addition to <, >, <=, and >=)? I thought that comparing pointers to 2 different arrays, even for equality, was undefined behavior.

8. Originally Posted by CornedBee
Undefined for relational operations (or pointers wouldn't be iterators). I believe it's iterator-dependent for equality. The standard doesn't say.

...

There are important use cases for having an iterator temporarily be a singular value, to have a default-constructible iterator.
My point is that objects where x == x is not true are ridiculous, whether those objects are "singular" or not. I'm not debating that we don't need default-constructible iterators, I'm saying that because they have default constructors they should at least self-compare consistently.

Yes, the standard does not define it. IMHO, a problem with the standard.

9. It's not particular to iterators, though. In fact, it's this way with iterators because it's already this way with pointers. Comparing invalid pointers for equality is undefined.

And the reason for that is that there is, or might be, or has been, hardware which traps upon such reads.

There's simply no use in comparing invalid pointers, especially not to themselves, so what's the point in requiring it to have a defined result?

10. There's simply no use in comparing invalid pointers, especially not to themselves, so what's the point in requiring it to have a defined result?
I agree. You can compare an orange to itself, but once you're dealing with bananas, who cares about oranges?

11. Originally Posted by dudeomanodude
I agree. You can compare an orange to itself, but once you're dealing with bananas, who cares about oranges?
Not necessarily true. I may want to compare different iterators for positioning purposes for instance. Or a reverse and forward iterator on the same object.

I think the argument is, there's no point in comparing invalid iterators.