Ответ 1
До С++ 11 потоки С++ неявно конвертируются в void*
. Результат будет NULL
, если поток не находится в состоянии без ошибок и что-то еще, если оно есть. Поэтому ifs == NULL
(не должен работать с nullptr
, см. Ниже) найдет и использует это преобразование, и поскольку ваше имя файла было неправильным, сравнение даст true.
В С++ 11 это было изменено на явное преобразование в bool
, причем false
указывает на ошибку и true
хороший поток, потому что преобразование void*
допускало слишком много бессмысленного кода, например ваш пример. Действительно, текущий компилятор в режиме С++ 11 или С++ 14 отклонит ваш фрагмент, вживую. Поскольку ваш код, по-видимому, не менее С++ 11, ваш компилятор не согласен, приняв его.
Эти преобразования допускают и предназначены для проверки ошибок следующим образом:
if ( !(ifs >> data) )
std::cout << "Reading data failed.";
или, аналогично вашему примеру:
std::ifstream ifs ("wrong_filename.txt");
if (!ifs)
std::cout << "Could not open file.";
Забавный факт дня: вы также можете использовать это для чистого цикла над файлом, например:
for (std::string line; std::getline(ifs, line);) {
// Process line
}