简体   繁体   English

C ++ Ifstream对象等于nullptr但不是指针吗?

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

I was trying a test program on failures of opening a file using ifstream . 我正在尝试使用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 ? 如果ifs不是pointer ,那么它如何等于nullptr

Until C++11, C++ streams are implicitly convertible to void* . 在C ++ 11之前,C ++流可以隐式转换为void* The result will be NULL if the stream is not in an errorless state and something else if it is. 如果流不处于无错误状态,则结果为NULL否则为NULL 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. 因此, ifs == NULL (不应与nullptr ,请参见下文)将找到并使用该转换,并且由于文件名错误,因此比较将得出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. 在C ++ 11中,这已更改为对bool的显式转换,其中false表示错误,而true表示true的流,因为void*转换允许太多不必要的代码,例如您的示例。 Indeed, a current compiler in C++11 or C++14 mode will reject your snippet, live . 实际上,当前处于C ++ 11或C ++ 14模式的编译器将拒绝您的代码片段live Since your code is obviously at least C++11, your compiler is non-conforming by accepting it. 由于您的代码显然至少是C ++ 11,因此您的编译器不接受它。

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, eg: 当今的有趣事实:您还可以使用它来干净地循环遍历文件,例如:

for (std::string line; std::getline(ifs, line);) {
    // Process line
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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