Search code examples
c++stdfstream

Why fstream methods returns references to "*this"?


I've recently started coding in C++, but I have long time writing in C. So i'm reading the methods from fstream class and I've figured out that every method which could be a procedure (returning nothing) is returning a reference to the object that called its method. (fstream& fstream::read(char_type* __s, streamsize __n) for example).

Why is done this way?

I'm coding a little layer on top of fstream class so I'm wondering if I should return a reference in my read methods too.

Thanks.


Solution

  • Returning a reference to the stream object itself gives you an excellent way to check the validity of I/O operations: If an operation fails, the stream object is in a fail state, which means that it will evaluate to false in a boolean context. Thus we can write:

    while (std::getline(instream, str)) { /* ... process line ... */ }
    
    if (anotherstream >> x >> y) { /* process x and y */ }
    else { /* error, at least one extraction failed */ }
    
    if (!laststream.read(buf, sizeof(buf)) { /* error */ }
    

    Note in particular the repeated call in the second example: Each extraction returns a reference to the stream object, and so we can concatenate multiple extractions in one statement, and if any of them fail, the entire operation will evaluate false.

    Here's a practical example, parsing lines of the form [x y z] from the standard input:

    for (std::string line; std::getline(std::cin, line); )
    {
        std::istringstream iss(line);
        char l, r;
        double x, y, z;
    
        if (!(iss >> l >> x >> y >> z >> r) || (l != '[') || (r != ']'))
        {
            std::cerr << "Malformed line ('" << line << "'), skipping.\n";
            continue;
        }
    
        std::cout << "You said: " << x << ", " << y << ", " << z << std::endl;
    }