When I run code like
istream s;
if (s)
// ...
I can test for the truth value of istream (or any ios object). From my understanding, this works the way it does because of how ios defines the operator! function. (For reference, http://www.cplusplus.com/reference/ios/ios/operatornot/.) My question is: why does putting s inside the if statement, as above, cause the operator! function to be evaluated? As a secondary question, if I put just any object inside an if statement, what are the possible ways that C++ will use to evaluate its truthiness?
In C++03, this check was done through the
operator void*member function, which returned a non-null pointer if the stream was in a good state and NULL otherwise. Since null pointers evaluate to false and non-null pointers evaluate to true, this check worked fine.It did have problems, though, since you could do this:
This would invoke the
operator void*function and print out either 0 or the address ofcout, depending on whether the stream was good. This isn’t a good thing, since the above code doesn’t appear to do that. Worse, you could doWhich causes undefined behavior if the stream isn’t good.
In C++11, this was changed so the stream has an
explicit operator boolmember function, which allows the stream to be explicitly cast to a bool. This eliminates the above problem and is the preferred way to support if checks on objects going forward.Hope this helps!