为什么ifstream对象可以与0进行比较?

时间:2013-09-04 16:50:37

标签: c++

我试图在大约20年前首次学习基础知识之后重新学习C ++,然后将其放在一边。那时我开始拿起一本我从中学到的书。这是他的一个例子(我已经发现它有一些过时的语法):

#include <fstream.h>
void main() {
    ifstream infile("iocopy.cpp");
    if (!infile) cerr << "couldn't open iopcopy.cpp" << endl;
    ... other junk
}

他对!上的infile运算符的解释是它“检查对象是否为非零”,这让我很困惑(对象为零意味着什么? )。所以我决定自己尝试一下:

#include <fstream>
#include <iostream>
void main () {
    std::ifstream f ("something");
//  if (f == 0) std::cout << "Couldn't open file" << std::endl;
    if (!f) std::cout << "Couldn't open file" << std::endl;
}

这可以按预期工作,如果文件不存在则显示消息,如果文件不存在则显示消息。如果我使用(f == 0)取消注释该行并注释掉以下行,它也可以工作。

我想我在这里找到了!运算符;我在其中一个头文件中找到了operator!,以返回fail字段。我很困惑为什么第一个例子(f == 0)有效,因为我没有看到任何似乎适用的operator==

那是怎么回事?可以将任何类类型的任何变量与0进行比较吗? ifstream有什么特别之处,那种类型的变量本质上是指针(可以比较为null或0)?或者是否有我错过的operator==重新定义?我更习惯像Java这样的语言,构造函数不可能返回null值,所以我很困惑。

2 个答案:

答案 0 :(得分:4)

<强> C ++ 03

basic_ios(基类ifstream)有一个operator void*,可以隐式转换为void*

0void*字面值的有效值,因此您要比较void*类型的值。

<强> C ++ 11

basic_ios(基类ifstream)有explicit operator bool,只能通过显式转换才能转换为bool。所以你的例子不应该编译。

根据C ++语言类型转换规则,

bool可以隐式转换为int,因此,如果operator bool不是explicit,那么您将比较输入int

答案 1 :(得分:3)

  

“检查对象是否为非零”

这不是一个正确的陈述。 basic_ios类模板(basic_istream模板从中继承)具有转换运算符,允许在条件下对其进行测试。特别是在C ++ 11之前,它们实现了对void*的隐式转换,如果流处于无效状态则返回0,否则返回不同的值。那是对象,但是为此目的生成的人为值。在C ++ 11中,转换是对bool的显式转换(并且测试f == 0将失败)