为什么 std::find_if 用于 std::istream_iterators 似乎是 return 最后一个元素?

Why does std::find_if used on std::istream_iterators seem to return the last element?

我正在通过 Andrew Koenig 和 Barbara E. Moo 的 Accelerated C++ 学习 C++。我试图了解输入运算符的工作原理及其与 STL 算法的关系。

这是让我感到困惑的一段代码:

#include <iostream>
#include <iterator>
#include <algorithm>
#include <cctype>

bool space(char c)
{
    return std::isspace(c);
}

int main()
{
    std::istream_iterator<char> i = std::find_if(
        std::istream_iterator<char>(std::cin),
        std::istream_iterator<char>(),
        space);
    std::cout << *i << std::endl;
    return 0;
}

代码编译正常,但是当我 运行 它在任何输入上输出的是最后输入的字符。例如,我预计 123 456 的输出是 但实际上是 6。同样,我预计 123456 的输出是一些错误,因为我们试图访问一个元素不存在,但输出又是 .我错过了什么?

Why doesn't 123 456 as input produce </code> as output?</p> </blockquote> <p>来自<a href="https://en.cppreference.com/w/cpp/iterator/istream_iterator" rel="nofollow noreferrer">cppreference</a>:</p> <blockquote> <p><strong>When reading characters, std::istream_iterator skips whitespace by default</strong> (unless disabled with std::noskipws or equivalent), while std::istreambuf_iterator does not.</p> </blockquote> <p>切换到 <code>std::istreambuf_iterator 会得到所需的行为:https://wandbox.org/permlink/RRt8kvyqyvbO1p8m


Why doesn't 123456 as input produce an error?

如果输入中没有 space,find_if 将 return 它的第二个参数,即 end-of-stream迭代器。

取消引用流末尾迭代器是 undefined behaviour,不保证会产生错误。事实上,它不能保证任何事情,这意味着您的程序可能只打印您输入的最后一个字符。