This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of CD1 status.

### 44. Iostreams use operator== on int_type values

Section: 31 [input.output] Status: CD1 Submitter: Nathan Myers Opened: 1998-08-06 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [input.output].

View all issues with CD1 status.

Discussion:

Many of the specifications for iostreams specify that character values or their int_type equivalents are compared using operators == or !=, though in other places traits::eq() or traits::eq_int_type is specified to be used throughout. This is an inconsistency; we should change uses of == and != to use the traits members instead.

Proposed resolution:

[Pre-Kona: Dietmar supplied wording]

List of changes to clause 27:

1. In lib.basic.ios.members paragraph 13 (postcondition clause for 'fill(cT)') change

   >          fillch == fill()

   to

   >          traits::eq(fillch, fill())

2. In lib.istream.unformatted paragraph 7 (effects clause for 'get(cT,streamsize,cT)'), third bullet, change

   >          c == delim for the next available input character c

   to

   >          traits::eq(c, delim) for the next available input character c

3. In lib.istream.unformatted paragraph 12 (effects clause for 'get(basic_streambuf<cT,Tr>&,cT)'), third bullet, change

   >          c == delim for the next available input character c

   to

   >          traits::eq(c, delim) for the next available input character c

4. In lib.istream.unformatted paragraph 17 (effects clause for 'getline(cT,streamsize,cT)'), second bullet, change

   >          c == delim for the next available input character c

   to

   >          traits::eq(c, delim) for the next available input character c

5. In lib.istream.unformatted paragraph 24 (effects clause for 'ignore(int,int_type)'), second bullet, change

   >          c == delim for the next available input character c

   to

   >          traits::eq_int_type(c, delim) for the next available input
   >          character c

6. In lib.istream.unformatted paragraph 25 (notes clause for 'ignore(int,int_type)'), second bullet, change

   >          The last condition will never occur if delim == traits::eof()

   to

   >          The last condition will never occur if
   >          traits::eq_int_type(delim, traits::eof()).

7. In lib.istream.sentry paragraph 6 (example implementation for the sentry constructor) change

   >          while ((c = is.rdbuf()->snextc()) != traits::eof()) {

   to

   >          while (!traits::eq_int_type(c = is.rdbuf()->snextc(), traits::eof())) {

List of changes to Chapter 21:

1. In lib.string::find paragraph 1 (effects clause for find()), second bullet, change

   >          at(xpos+I) == str.at(I) for all elements ...

   to

   >          traits::eq(at(xpos+I), str.at(I)) for all elements ...

2. In lib.string::rfind paragraph 1 (effects clause for rfind()), second bullet, change

   >          at(xpos+I) == str.at(I) for all elements ...

   to

   >          traits::eq(at(xpos+I), str.at(I)) for all elements ...

3. In lib.string::find.first.of paragraph 1 (effects clause for find_first_of()), second bullet, change

   >          at(xpos+I) == str.at(I) for all elements ...

   to

   >          traits::eq(at(xpos+I), str.at(I)) for all elements ...

4. In lib.string::find.last.of paragraph 1 (effects clause for find_last_of()), second bullet, change

   >          at(xpos+I) == str.at(I) for all elements ...

   to

   >          traits::eq(at(xpos+I), str.at(I)) for all elements ...

5. In lib.string::find.first.not.of paragraph 1 (effects clause for find_first_not_of()), second bullet, change

   >          at(xpos+I) == str.at(I) for all elements ...

   to

   >          traits::eq(at(xpos+I), str.at(I)) for all elements ...

6. In lib.string::find.last.not.of paragraph 1 (effects clause for find_last_not_of()), second bullet, change

   >          at(xpos+I) == str.at(I) for all elements ...

   to

   >          traits::eq(at(xpos+I), str.at(I)) for all elements ...

7. In lib.string.ios paragraph 5 (effects clause for getline()), second bullet, change

   >          c == delim for the next available input character c

   to

   >          traits::eq(c, delim) for the next available input character c

Notes:

- Fixing this issue highlights another sloppyness in lib.istream.unformatted paragraph 24: this clause mentions a "character" which is then compared to an 'int_type' (see item 5. in the list below). It is not clear whether this requires explicit words and if so what these words are supposed to be. A similar issue exists, BTW, for operator*() of istreambuf_iterator which returns the result of sgetc() as a character type (see lib.istreambuf.iterator::op* paragraph 1), and for operator++() of istreambuf_iterator which passes the result of sbumpc() to a constructor taking a char_type (see lib.istreambuf.iterator::operator++ paragraph 3). Similarily, the assignment operator ostreambuf_iterator passes a char_type to a function taking an int_type (see lib.ostreambuf.iter.ops paragraph 1).
- It is inconsistent to use comparisons using the traits functions in Chapter 27 while not using them in Chapter 21, especially as some of the inconsistent uses actually involve streams (eg. getline() on streams). To avoid leaving this issue open still longer due to this inconsistency (it is open since 1998), a list of changes to Chapter 21 is below.
- In Chapter 24 there are several places with statements like "the end of stream is reached (streambuf_type::sgetc() returns traits::eof())" (lib.istreambuf.iterator paragraph 1, lib.ostreambuf.iter.ops paragraph 5). It is unclear whether these should be clarified to use traits::eq_int_type() for detecting traits::eof().