Search code examples
c++c++11type-conversioniostreamexplicit-conversion

Is "if (getline(fin, str)) {}" conforming to the C++11 standard?


I checked the C++11 standard and found the following facts:

  1. std::getline(fin, str) returns a basic_ios object, whose class has a member function explicit operator bool() const;

  2. 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?


Solution

  • 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 declaration T 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 declaration bool t(e); is well-formed, for some invented temporary variable t (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.