111. istreambuf_iterator::equal overspecified, inefficient

Section: 24.6.4.4 [istreambuf.iterator.ops] Status: NAD Submitter: Nathan Myers Opened: 1998-10-15 Last modified: 2017-11-29

Priority: Not Prioritized

View all other issues in [istreambuf.iterator.ops].

View all issues with NAD status.

Discussion:

The member istreambuf_iterator<>::equal is specified to be unnecessarily inefficient. While this does not affect the efficiency of conforming implementations of iostreams, because they can "reach into" the iterators and bypass this function, it does affect users who use istreambuf_iterators.

The inefficiency results from a too-scrupulous definition, which requires a "true" result if neither iterator is at eof. In practice these iterators can only usefully be compared with the "eof" value, so the extra test implied provides no benefit, but slows down users' code.

The solution is to weaken the requirement on the function to return true only if both iterators are at eof.

[ Summit: ]

Reopened by Alisdair.

[ Post Summit Daniel adds: ]

Recommend NAD. The proposed wording would violate the axioms of concept requirement EqualityComparable axioms as part of concept InputIterator and more specifically it would violate the explicit wording of 24.3.5.3 [input.iterators]/7:

If two iterators a and b of the same type are equal, then either a and b are both dereferenceable or else neither is dereferenceable.

[ 2009-07 Frankfurt ]

Agree NAD.

Proposed resolution:

Replace [istreambuf.iterator::equal], paragraph 1,

-1- Returns: true if and only if both iterators are at end-of-stream, or neither is at end-of-stream, regardless of what streambuf object they use.

with

-1- Returns: true if and only if both iterators are at end-of-stream, regardless of what streambuf object they use.

Rationale:

It is not clear that this is a genuine defect. Additionally, the LWG was reluctant to make a change that would result in operator== not being a equivalence relation. One consequence of this change is that an algorithm that's passed the range [i, i) would no longer treat it as an empty range.