1129. istream(buf)_iterator should support literal sentinel value

Section: [istream.iterator.cons], 25.6.4 [istreambuf.iterator] Status: Resolved Submitter: Alisdair Meredith Opened: 2009-05-30 Last modified: 2016-01-28 10:19:27 UTC

Priority: Not Prioritized

View all other issues in [istream.iterator.cons].

View all issues with Resolved status.


istream_iterator and istreambuf_iterator should support literal sentinel values. The default constructor is frequently used to terminate ranges, and could easily be a literal value for istreambuf_iterator, and istream_iterator when iterating value types. A little more work using a suitably sized/aligned char-array for storage (or an updated component like boost::optional proposed for TR2) would allow istream_iterator to support constexpr default constructor in all cases, although we might leave this tweak as a QoI issue. Note that requiring constexpr be supported also allows us to place no-throw guarantees on this constructor too.

[ 2009-06-02 Daniel adds: ]

I agree with the usefulness of the issue suggestion, but we need to ensure that istream_iterator can satisfy be literal if needed. Currently this is not clear, because 25.6.2 [istream.iterator]/3 declares a copy constructor and a destructor and explains their semantic in [istream.iterator.cons]/3+4.

The prototype semantic specification is ok (although it seems somewhat redundant to me, because the semantic doesn't say anything interesting in both cases), but for support of trivial class types we also need a trivial copy constructor and destructor as of 11 [class]/6. The current non-informative specification of these two special members suggests to remove their explicit declaration in the class and add explicit wording that says that if T is trivial a default constructed iterator is also literal, alternatively it would be possible to mark both as defaulted and add explicit (memberwise) wording that guarantees that they are trivial.

Btw.: I'm quite sure that the istreambuf_iterator additions to ensure triviality are not sufficient as suggested, because the library does not yet give general guarantees that a defaulted special member declaration makes this member also trivial. Note that e.g. the atomic types do give a general statement!

Finally there is a wording issue: There does not exist something like a "literal constructor". The core language uses the term "constexpr constructor" for this.


  1. Change 25.6.2 [istream.iterator]/3 as indicated:

    constexpr istream_iterator();
    istream_iterator(istream_type& s);
    istream_iterator(const istream_iterator<T,charT,traits,Distance>& x) = default;
    ~istream_iterator() = default;
  2. Change [istream.iterator.cons]/1 as indicated:

    constexpr istream_iterator();

    -1- Effects: Constructs the end-of-stream iterator. If T is a literal type, then this constructor shall be a constexpr constructor.

  3. Change [istream.iterator.cons]/3 as indicated:

    istream_iterator(const istream_iterator<T,charT,traits,Distance>& x) = default;

    -3- Effects: Constructs a copy of x. If T is a literal type, then this constructor shall be a trivial copy constructor.

  4. Change [istream.iterator.cons]/4 as indicated:

    ~istream_iterator() = default;

    -4- Effects: The iterator is destroyed. If T is a literal type, then this destructor shall be a trivial destructor.

  5. Change 25.6.4 [istreambuf.iterator] before p. 1 as indicated:

    constexpr istreambuf_iterator() throw();
    istreambuf_iterator(const istreambuf_iterator&)  throw() = default;
    ~istreambuf_iterator()  throw() = default;
  6. Change 25.6.4 [istreambuf.iterator]/1 as indicated:

    [..] The default constructor istreambuf_iterator() and the constructor istreambuf_iterator(0) both construct an end of stream iterator object suitable for use as an end-of-range. All specializations of istreambuf_iterator shall have a trivial copy constructor, a constexpr default constructor and a trivial destructor.

[ 2009-10 Santa Cruz: ]

NAD EditorialResolved. Addressed by N2994.

Proposed resolution:

25.6.2 [istream.iterator] para 3

constexpr istream_iterator(); [istream.iterator.cons]

constexpr istream_iterator();

-1- Effects: Constructs the end-of-stream iterator. If T is a literal type, then this constructor shall be a literal constructor.

25.6.4 [istreambuf.iterator]

constexpr istreambuf_iterator() throw();