27 Iterators library [iterators]

27.6 Stream iterators [stream.iterators]

27.6.1 Class template istream_­iterator [istream.iterator]

The class template istream_­iterator is an input iterator ([input.iterators]) that reads (using operator>>) successive elements from the input stream for which it was constructed.
After it is constructed, and every time ++ is used, the iterator reads and stores a value of T.
If the iterator fails to read and store a value of T (fail() on the stream returns true), the iterator becomes equal to the end-of-stream iterator value.
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.
The result of operator* on an end-of-stream iterator is not defined.
For any other iterator value a const T& is returned.
The result of operator-> on an end-of-stream iterator is not defined.
For any other iterator value a const T* is returned.
The behavior of a program that applies operator++() to an end-of-stream iterator is undefined.
It is impossible to store things into istream iterators.
The type T shall meet the DefaultConstructible, CopyConstructible, and CopyAssignable requirements.
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.
namespace std {
  template <class T, class charT = char, class traits = char_traits<charT>,
      class Distance = ptrdiff_t>
  class istream_iterator {
  public:
    using iterator_category = input_iterator_tag;
    using value_type        = T;
    using difference_type   = Distance;
    using pointer           = const T*;
    using reference         = const T&;
    using char_type         = charT;
    using traits_type       = traits;
    using istream_type      = basic_istream<charT,traits>;

    constexpr istream_iterator();
    istream_iterator(istream_type& s);
    istream_iterator(const istream_iterator& x) = default;
    ~istream_iterator() = default;

    const T& operator*() const;
    const T* operator->() const;
    istream_iterator& operator++();
    istream_iterator  operator++(int);
  private:
    basic_istream<charT,traits>* in_stream; // exposition only
    T value;                                // exposition only
  };

  template <class T, class charT, class traits, class Distance>
    bool operator==(const istream_iterator<T,charT,traits,Distance>& x,
            const istream_iterator<T,charT,traits,Distance>& y);
  template <class T, class charT, class traits, class Distance>
    bool operator!=(const istream_iterator<T,charT,traits,Distance>& x,
            const istream_iterator<T,charT,traits,Distance>& y);
}

27.6.1.1 istream_­iterator constructors and destructor [istream.iterator.cons]

constexpr istream_iterator();
Effects: Constructs the end-of-stream iterator.
If is_­trivially_­default_­constructible_­v<T> is true, then this constructor is a constexpr constructor.
Postconditions: in_­stream == 0.
istream_iterator(istream_type& s);
Effects: Initializes in_­stream with addressof(s).
value may be initialized during construction or the first time it is referenced.
Postconditions: in_­stream == addressof(s).
istream_iterator(const istream_iterator& x) = default;
Effects: Constructs a copy of x.
If is_­trivially_­copy_­constructible_­v<T> is true, then this constructor is a trivial copy constructor.
Postconditions: in_­stream == x.in_­stream.
~istream_iterator() = default;
Effects: The iterator is destroyed.
If is_­trivially_­destructible_­v<T> is true, then this destructor is a trivial destructor.

27.6.1.2 istream_­iterator operations [istream.iterator.ops]

const T& operator*() const;
Returns: value.
const T* operator->() const;
Returns: addressof(operator*()).
istream_iterator& operator++();
Requires: in_­stream != 0.
Effects: As if by: *in_­stream >> value;
Returns: *this.
istream_iterator operator++(int);
Requires: in_­stream != 0.
Effects: As if by:
istream_iterator tmp = *this;
*in_stream >> value;
return (tmp);
template <class T, class charT, class traits, class Distance> bool operator==(const istream_iterator<T,charT,traits,Distance>& x, const istream_iterator<T,charT,traits,Distance>& y);
Returns: x.in_­stream == y.in_­stream.
template <class T, class charT, class traits, class Distance> bool operator!=(const istream_iterator<T,charT,traits,Distance>& x, const istream_iterator<T,charT,traits,Distance>& y);
Returns: !(x == y)