当 std::istream_iterator<int>(std::cin) 等于结束迭代器 std::istream_iterator<int>() 时会发生什么

What happens when std::istream_iterator<int>(std::cin) Equals to the end iterator std::istream_iterator<int>()

我正在通过 checking/writing 个不同的例子来学习迭代器。在一个这样的例子中(下面给出),当我输入一个无效的类型说 char 到输入流时,下一个 cout 语句不会被执行。示例如下:

#include <iostream>
#include <iterator>
int main()
{
   
    std::istream_iterator<int> starting_it(std::cin), ending_it;
   
    while(starting_it != ending_it)
    {
       
       *starting_it++;//lets say i entered the character f on the console and pressed enter then why is the next cout statement not executed
       std::cout<<"after"<<std::endl;//this line is not printed on the console after an invalid type is encountered
    }
    return 0;
}

现在,当我执行此程序并输入值 1 2 f 然后按回车键时,控制台上只会打印两个“after”。 我的问题是为什么“after”没有在屏幕上打印 3 次?

这就是我认为正在发生的事情:

第 1 步。由于在开始时 starting_itending_it 不相等,我们进入 while 循环。

第 2 步。现在,starting_it 递增,同时从 cin 中读取一个值。

第 3 步。接下来,返回 starting_it 的旧值,我们在其上应用 * 运算符。在当前迭代中,this 的值为 1,该值在语句末尾被丢弃。接下来cout<<"after"<<std::endl;被执行并打印在控制台上。

第 4 步。现在又一次,因为我们没有遇到文件结尾或任何输入错误,所以我们转到 while 循环的下一次迭代。

Step 5. 重复Step1-Step4。这次唯一的不同是,在第 4 步结束时,当我们取消引用 starting_it 时,我们得到值 2.

第六步。现在我们再次进入下一个迭代。但是这次 starting_it 递增时,读取了无效类型的 char,因此 starting_it 等于结束迭代器。

现在我的问题是在步骤中应该执行语句std::cout<<"after"<<std::endl并且“after”应该打印在console.And然后条件of while 应该检查哪个是假的。但为什么这没有发生呢?为什么我们在控制台上打印的只是两个“after”,而不是3个。这是不是因为ostream也出错了。实际上,似乎每当我们在输入流上遇到错误或 eof 时,我们就会跳出 while 循环。另外,我的解释是否正确,如果不正确请指正。

我附上了输出的屏幕截图。

std::istream_iterator 预读:首先读入构造函数,随后读入 operator++operator* returns 之前读取的缓存值。如果任何读取失败,则迭代器变为等于结束迭代器。

这就是您的示例中发生的情况。 starting_it 在构造函数中读取 1。循环的第一次迭代读取 2 并打印第一个 after。循环的第二次迭代尝试读取 f(此时 starting_it 等于 ending_it)并打印第二个 after。那么循环就存在了。

总而言之,执行了三个读取 - 一个在构造函数中,两个在两个 operator++ 调用中,对应两次 after 被打印。