[Accelerated C++] - Function read_homework returns istream&. Why??

I am reading through the book, and on p. 57 there is the code for this function, which should take as inputs the grades of the homework of a student and construct a vector homework out of it. The code is as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    #include <iostream>
    #include <vector>

      using namespace std;

      istream& read_hw(istream& in, vector<double>& hw)
     {
	if (in) {
		// get rid of previous contents
		hw.clear();

		// read homework grades
		double x;
		while (in >> x)
			hw.push_back(x);

		// clear the stream so that input will work for the next student
		in.clear();
	}
	return in;
        }


I have several problems with this function. But mostly of all: why does this function returns "in"? What is the point? What does that mean, concretely?? Was it not enough to declare it void and so storing the vector homework directly?

Also, another issue I find is in the instruction in.clear(); what does this instruction do and why is it necessary?

I would like to test this function and I have written a main like this:

1
2
3
4
5
6
7
8
9
      int main()
     {
       cout << "Enter your homework grades" << endl;

        vector<double> homework;
        read_hw(cin, homework);

        return 0;
     }


but this doesn't really do anything other than asking for the homework grades. Is it any chance to "see" in the output the "cin" that the function returns?

I am definitely very confused by this function. :(
Last edited on
closed account (E0p9LyTq)
Is it any chance to "see" in the output the "cin" that the function returns?


The function is using references so you don't copy the std::cin stream, into and out of your function.
Ok, but what's the point of having it returning istream?
> But mostly of all: why does this function returns "in"? What is the point? What does that mean, concretely?? Was it not enough to declare it void and so storing the vector homework directly?

Returning a value can make a function more flexible, in the meaning that it can be used e.g. in an if statement.
That’s exactly what the author says:
“ Returning the stream allows our caller to write
if (read_hw(cin, homework)){/*...*/}
as an abbreviation for
read_hw(cin, homework);
if (cin) {/*...*/} ”


> Also, another issue I find is in the instruction in.clear(); what does this instruction do and why is it necessary?

It does what is written here: http://www.cplusplus.com/reference/ios/ios/clear/ :-)

Let’s assume while reading the grades of the homework the function runs into some error.
Were that the case, the value contained in the istream would not be valid and should not be used; so it could be a good idea to purge it.
And… yes, the author explains that too:
“...all we must do is tell the library to disregard whatever condition caused the input attempt to fail, be it end-of-file or invalid input. We do so by calling in.clear() to reset the error state inside in...”


> Is it any chance to "see" in the output the "cin" that the function returns?
Sorry, did you mean the output of "homework"? Because in "cin" you will only find the last unread character, if any. Since you need to stop "read_hw()" by providing an input that is not a double (let's say a letter), that's what you will find there.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
int main()
{
   cout << "Enter your homework grades" << endl;

   vector<double> homework;
   if (read_hw(cin, homework)) {
      
      char text[256]; // reasonable dimension
      cin.getline(text, 255);
      cout << "cin contains: \"" << text 
            << "\"" << endl;
      
      // c++11 range-based for loop
      for( const auto it : homework ) {
         cout << it << ' ';
      }
      cout << endl;
      
      // 'traditional' for loop
      for( int i=0; i < homework.size(); i++ ) {
         cout << homework[i] << ' ';
      }
      cout << endl;
   }

   return 0;
}

Topic archived. No new replies allowed.