# std::istream_iterator

< cpp‎ | iterator

定义于头文件 `<iterator>` |  |
template< class T, class CharT = char, class Traits = std::char_traits<CharT>, class Distance = std::ptrdiff_t > class istream_iterator: public std::iterator<std::input_iterator_tag, T, Distance, const T*, const T&> |  | (C++17 前)
template< class T, class CharT = char, class Traits = std::char_traits<CharT>, class Distance = std::ptrdiff_t > class istream_iterator; |  | (C++17 起)

`std::istream_iterator` 是单趟输入迭代器，从为之创建迭代器的 std::basic_istream 对象读取 `T` 类型的相继对象，通过调用适当的 `operator>>` 。实际读取操作在自增，而非解引用迭代器时进行。在构造迭代器时读取首个对象。解引用只返回最近读取的对象的副本。

默认构造的 `std::istream_iterator` 被称为流尾迭代器。合法的 `std::istream_iterator` 抵达底层流尾时，它变得等于流尾迭代器。解引用和进一步自增它导致未定义行为。

`std::istream_iterator` 的典型实现保有二个数据成员：指向关联 std::basic_istream 对象的指针和最近读取的 `T` 类型值。

`T` 必须满足可默认构造 (DefaultConstructible) 、可复制构造 (CopyConstructible) 和可复制赋值 (CopyAssignable) 要求。

### 成员类型

成员类型 | 定义
`iterator_category` | std::input_iterator_tag
`value_type` | T
`difference_type` | Distance
`pointer` | const T*
`reference` | const T&
`char_type` | `CharT`
`traits_type` | `Traits`
`istream_type` | std::basic_istream<CharT, Traits>

要求通过从 std::iterator<std::input_iterator_tag, T, Distance, const T*, const T&> 继承获得成员类型 `iterator_category`、 `value_type`、 `difference_type`、 `pointer` 及 `reference` 。 | (C++17 前)

### 成员函数

(构造函数) | 构造新的 istream_iterator (公开成员函数)
(析构函数) | 析构 istream_iterator ，包含缓冲的值 (公开成员函数)
operator*operator-> | 返回当前元素 (公开成员函数)
operator++operator++(int) | 推进迭代器 (公开成员函数)

### 非成员函数

operator==operator!= (C++20 中移除) | 比较两个 `istream_iterator` (函数模板)

### 注解

读字符时， `std::istream_iterator` 默认跳过空白符（除非用 std::noskipws 或等价物禁用，而 std::istreambuf_iterator 不跳过。另外， std::istreambuf_iterator 更有效率，因为它避免对每个字符构造并析构一次 sentry 对象的开销。

### 示例

    #include <iostream>
    #include <sstream>
    #include <iterator>
    #include <numeric>
    #include <algorithm>

    int main()
    {
        std::istringstream str("0.1 0.2 0.3 0.4");
        std::partial_sum(std::istream_iterator<double>(str),
                         std::istream_iterator<double>(),
                         std::ostream_iterator<double>(std::cout, " "));

        std::istringstream str2("1 3 5 7 8 9 10");
        std::cout << "\nThe first even number is " <<
            *std::find_if(std::istream_iterator<int>(str2),
                          std::istream_iterator<int>(),
                          [](int i){ return i % 2 == 0; })
            << ".\n";
        // " 9 10" 留在流中
    }

输出：

    0.1 0.3 0.6 1
    The first even number is 8.

### 缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

DR | 应用于 | 出版时的行为 | 正确行为
--- | --- | --- | ---
P0738R2 | C++98 | 首次读取可以延迟到首次解引用 | 首次读取在构造函数中进行

### 参阅

ostream_iterator | 写入 std::basic_ostream 的输出迭代器 (类模板)
istreambuf_iterator | 从 std::basic_streambuf 读取的输入迭代器 (类模板)