简体   繁体   中英

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

i am learning about iterators by checking/writing different examples. In one such example(given below) when i enter an invalid type say char into the input stream the next cout statement is not executed. The example is as follows:

#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;
}

Now when i execute this program and enter the values say 1 2 f and then press enter, then only two "after" are printed on the console. My question is why isn't "after" printed 3 times on the screen?

This is what i think is happening:

Step 1. Since at the beginnnig starting_it and ending_it are not equal we go inside the while loop.

Step 2. Now, starting_it is incremented and also at the same time a value is read from cin .

Step 3. Next, the old value of starting_it is returned on which we apply the * operator. This in the current iteration has value 1 which is discarded at the end of the statement. Next cout<<"after"<<std::endl; is executed and printed on the console.

Step 4. Now again since we have not encountered end of file or any input error so we go to the next iteration of the while loop.

Step 5. Step1-Step4 are repeated. The only difference this time is that at the end of Step4 when we dereference starting_it we get the value 2.

Step6 . Now again we go into the next iteration. But this time when starting_it is incremented, an invalid type of char is read and so starting_it is made equal to the end iterator.

Now my question is that in the step the statement std::cout<<"after"<<std::endl should be executed and "after" should be printed on the console.And then the condition of while should be checked which comes out to be false. But why isn't this happening? Why do we have only two "after" printed on the console instead of 3. Is this because ostream is also in error. Effectively, it seems whenever we encounter an error or eof on input stream, we break out of the while loop. Also, is my explanation correct, if not then please correct me.

I have attached the screenshot of the output.

截屏

std::istream_iterator reads ahead: the first read in constructor, subsequent reads in operator++ . operator* returns the previously read, cached value. If any of the reads fail, the iterator becomes equal to the end iterator.

So this is what happens in your example. starting_it reads 1 in constructor. The first iteration of the loop reads 2 and prints the first after . The second iteration of the loop attempts to read f (at which point starting_it becomes equal to ending_it ) and prints the second after . Then the loop exists.

All in all, three reads are executed - one in constructor, two in the two operator++ calls, corresponding to the two times after is printed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM