Somewhat obscure is what it means for two objects of type istreambuf_iterator to be equivalent:
Two istreambuf_iterator objects are equivalent if both iterators are end-of-stream iterators
or if neither of them is an end-of-stream iterator (whether the output buffer is the same doesn’t
matter). One possibility to get an end-of-stream iterator is to construct an iterator with the default
constructor. In addition, an istreambuf_iterator becomes an end-of-stream iterator when an attempt
is made to advance the iterator past the end of the stream (in other words, if sbumpc() returns
traits_type::eof(). This behavior has two major implications