为什么istream对象可以用作bool表达式?

26

有人知道为什么istream对象可以用作布尔表达式吗?例如:

ifstream input("tmp");
int iValue;
while (input >> iValue)
    //do something;

在这里,input >> iValue返回一个ifstream对象的引用。我想知道为什么这个对象可以用作布尔表达式。
我查看了ifstream类,并发现这可能是由于以下成员函数:

operator void * ( ) const;

请参阅此处以获取有关此函数的详细信息。
如果可以的话,有人能向我解释一下这个函数吗?此函数的原型与通常的运算符重载声明不同。这个函数的返回类型是什么?
如果不是这样,那么为什么ifstream对象可以用作布尔表达式?
期待您的帮助!

虽然有一个直截了当的答案,但问题问得很好。 - Joe McGrath
1
自C++11起,实际上有explicit operator bool() - M.M
2个回答

24

在C++11中,启用了一个确切的机制,使得能够将istream用作布尔表达式。以前是隐式转换为void*,就像你发现的那样。而在C++11中,它改为显式转换为bool

允许在布尔表达式中使用istream或ostream,是为了让C++程序员可以继续将具有副作用的表达式用作whilefor循环的条件:

SomeType v;

while( stream >> v )
{
    // ...
}

程序员这样做并且希望这样做的原因是,它提供了更简洁的代码,更容易一眼看懂,而不是比如……

for( ;; )
{
    SomeType v;
    
    stream >> v;
    if( stream.fail() )
    {
        break;
    }
    // ...
}

然而,在某些情况下,即使是这样详细的结构也可能更可取。这取决于具体情况。


7

这是一个向给定类型转换的强制类型转换运算符。 operator T() 是向类型 T 转换的强制类型转换运算符。在 if 语句中,ifstream 被转换为 void*,然后将 void* 转换为 bool


4
“void* 转换为 bool”并不正确。相反,我会说“void* 与0进行比较”。 - iammilind
谢谢您很快地回复,我明白了。我还有一个问题:如果一个类中有两个类型转换函数,一个是将其转换为int,另一个是将其转换为int *。对于调用if(obj)的情况,将调用哪个转换函数?为什么?谢谢。 - cheng
4
没问题,@iammilind的说法是正确的。指针被转换为布尔类型。请查看§4.12和§6.4.1。 - R. Martinho Fernandes
@R.MartinhoFernandes,您是指C++11吗?据我所知,在C++03中,只有普通的void*0进行比较。[附言:我没有对这个答案进行投票。] - iammilind
@iammilind:我提供的参考编号来自C++11标准。C++03中的编号可能不同。但是行为是相同的。void*可以转换为bool,并且在if语句中所有内容都会被转换为bool - R. Martinho Fernandes
3
与0的比较是实现转换的方式,但说它被转换了也是完全正确的。 - Puppy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接