I checked the C++11 standard and found the following facts:
std::getline(fin, str)
returns a basic_ios
object, whose class has a member function explicit operator bool() const;
The class basic_ios
doesn't have a member function operator void*() const;
as pre-C++11.
So, I think if (getline(fin, str)) {}
is not standard conforming. It should be written as
if (bool(getline(fin, str)){}
. (However, VC++ 2012 gives a warning on this usage. i.e. force void* to bool)
Am I correct?
David is correct, and here are the quotes to back him up. In §12.3.2/2, the Standard says
A conversion function may be explicit (7.1.2), in which case it is only considered as a user-defined conversion for direct-initialization (8.5). Otherwise, user-defined conversions are not restricted to use in assignments and initializations. [ Example:
class Y { }; struct Z { explicit operator Y() const; }; void h(Z z) { Y y1(z); // OK: direct-initialization Y y2 = z; // ill-formed: copy-initialization Y y3 = (Y)z; // OK: cast notation }
— end example]
Some places where this contextual conversion happens is in the operand to !
, the operands to &&
, and the condition of an if
.
So direct initialisation can make use of explicit conversion operators, and in §4/3,
An expression e can be implicitly converted to a type
T
if and only if the declarationT t=e;
is well-formed, for some invented temporary variable t (8.5). Certain language constructs require that an expression be converted to a Boolean value. An expression e appearing in such a context is said to be contextually converted to bool and is well-formed if and only if the declarationbool t(e);
is well-formed, for some invented temporary variablet
(8.5)...
So as you can see, the standard specifies as-if direct initialisation for contextual conversions, so that's why explicit conversions work in if
conditions.