Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Ifstream object equals nullptr but it isn't a pointer?

Tags:

c++

I was trying a test program on failures of opening a file using ifstream. The code is below :-

#include <iostream>
#include <fstream>
#include <type_traits>
using namespace std;
int main()
{
    ifstream ifs ("wrong_filename.txt");
    cout << boolalpha;
    cout << is_pointer<decltype(ifs)>::value <<"\n";
    cout << (ifs==nullptr);
    return 0;
}

Output is :-

false
true

If ifs is not a pointer, then how does it equal to nullptr?

like image 684
Anwesha Avatar asked Oct 17 '15 13:10

Anwesha


1 Answers

Until C++11, C++ streams are implicitly convertible to void*. The result will be NULL if the stream is not in an errorless state and something else if it is. So ifs == NULL (should not work with nullptr, see below) will find and use that conversion, and since your filename was wrong, the comparison will yield true.

In C++11, this was changed to an explicit conversion to bool, with false indicating an error and true a good stream, because the void* conversion allowed too much nonsensical code, such as your example. Indeed, a current compiler in C++11 or C++14 mode will reject your snippet, live. Since your code is obviously at least C++11, your compiler is non-conforming by accepting it.

Those conversions allow and are intended for error checks like this:

if ( !(ifs >> data) )
    std::cout << "Reading data failed.";

or, analogous to your example:

std::ifstream ifs ("wrong_filename.txt");
if (!ifs)
    std::cout << "Could not open file.";

Fun fact of the day: You can also use this to cleanly loop over a file, e.g.:

for (std::string line; std::getline(ifs, line);) {
    // Process line
}
like image 164
Baum mit Augen Avatar answered Oct 21 '22 17:10

Baum mit Augen