You are conflating two different issues.
istream_iterator
is an input iterator, not a forward iterator, so the C++14 change you cited doesn't apply to it at all. You are allowed to compare istream_iterator
s in that manner because they are explicitly specified to allow such comparisons. The standard says that (§24.6.1 [istream.iterator])
The constructor with no arguments istream_iterator()
always
constructs an end-of-stream input iterator object, which is the only
legitimate iterator to be used for the end condition. [...]
Two end-of-stream iterators are always equal. An end-of-stream
iterator is not equal to a non-end-of-stream iterator. Two
non-end-of-stream iterators are equal when they are constructed from
the same stream.
For forward iterators (which also includes bidirectional and random access ones) in general, value-initialized iterators are made comparable to each other in C++14. If your standard library implements it, then you can compare two value-initialized iterators. This allows you to create an empty range without an underlying container. However, you are still not allowed to compare a non-singular iterator to a value-initialized iterator. The following code has undefined behavior even in C++14:
std::list<int> l;
if(l.begin() == std::list<int>::iterator())
foo();
else
bar();
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…