1

Compile this code :

#include <set>
#include <iostream>

int main(int argc, char * argv[]){
  std::set<int> test;

  std::cout << (test.end() == std::set<int>::iterator{}) << std::endl;
  std::cout << (test.begin() == std::set<int>::iterator{}) << std::endl;
  std::cout << (test.begin() == test.end()) << std::endl;

  return 0;
}

It outputs (tested on gcc 11.1 and clang 12.0.0):

0
0
1

...However, if I refer to https://timsong-cpp.github.io/cppwp/n4659/iterators#forward.iterators-2

The domain of == for forward iterators is that of iterators over the same underlying sequence. However, value-initialized iterators may be compared and shall compare equal to other value-initialized iterators of the same type. [ Note: Value-initialized iterators behave as if they refer past the end of the same empty sequence.  — end note ]

...Then std::set<int>::iterator{} is what I understand to be "value-initialized" (note that I get the same result using a temporary variable), and I would expect the output to be :

1
1
1

What am I missing ?

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
hl037_
  • 3,520
  • 1
  • 27
  • 58
  • 3
    Where does this say that value-initialized iterators should compare equal to end iterators? – HolyBlackCat Jun 25 '21 at 21:31
  • That comparison is only valid for iterators not bound to a container, like stream iterators or filesystem iterators etc. – Ted Lyngmo Jun 25 '21 at 21:34
  • 2
    Related: [Is it well-defined to compare with a value-initialized iterator?](https://stackoverflow.com/questions/26241878/), specifically [this answer](https://stackoverflow.com/a/26241969/65863) can be applied to this question. – Remy Lebeau Jun 25 '21 at 21:40

2 Answers2

4

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

So... one can compare iterators from the same sequence with ==.

However, value-initialized iterators may be compared and shall compare equal to other value-initialized iterators of the same type.

So... one can compare two value-initialized iterators of the same type with ==.

Note: Value-initialized iterators behave as if they refer past the end of the same empty sequence.

Notes are not normative, but this is describing that there is some empty sequence hidden from you, and the value-initialized iterators act as if they refer to the past the end iterator of this sequence.

This is saying that it is as if the standard library instantiated for itself a std::set<int> and a value-initialized iterator referred to the .end() of that.

The note is consistent with the above. If value-initialized iterators act as if they all point into the same sequence, at the same point, they will be comparable and compare equal.

Jeff Garrett
  • 5,863
  • 1
  • 13
  • 12
3

It's undefined behavior to compare value-initialized iterators to iterators from a sequence.

"Value-initialized iterators behave as if they refer past the end of the same empty sequence" indicates that they cannot be dereferenced or advanced.

Mooing Duck
  • 64,318
  • 19
  • 100
  • 158
  • Ok for this point, but what about the note "Value-initialized iterators behave as if they refer past the end of the same empty sequence" ? – hl037_ Jun 25 '21 at 21:32
  • @hl037_: That indicates that they cannot be dereferenced or advanced. – Mooing Duck Jun 25 '21 at 21:33
  • 1
    Well, this contradict what is said here : https://stackoverflow.com/a/64101477/1745291 But the answer from @Jeff Garret sonds right – hl037_ Jun 25 '21 at 21:49
  • 2
    @hl037_ This doesn't contradict anything; you appear to be confusing the end iterator _for a specific sequence/container_, with the a non-normative "past the end iterator" note for an arbitrary empty sequence. A value-initialized iterator **behaves** like a past-the-end iterator for _some empty sequence_; which just means you can compare it to another **from the same sequence** (e.g. another value-initialized iterator), but it cannot be dereferenced. It's always UB to compare iterators from between different sequences -- and treating this like the `end` for your sequence is simply UB – Human-Compiler Jun 25 '21 at 22:35