type dynamic_cast cast c++ c++11 type-conversion iostream explicit-conversion

dynamic_cast - Es "if(getline(fin, str)){}" conforme al estándar C++ 11?



dynamic_cast c++ (3)

Revisé el estándar C ++ 11 y encontré los siguientes hechos:

  1. std::getline(fin, str) devuelve un objeto basic_ios , cuya clase tiene una función miembro explicit operator bool() const;

  2. La clase basic_ios no tiene un operator void*() const; función miembro operator void*() const; como pre-C ++ 11.

Entonces, creo if (getline(fin, str)) {} no es estándar. Debe escribirse como

if (bool(getline(fin, str)){} . (Sin embargo, VC ++ 2012 da una advertencia sobre este uso, es decir, force void * to bool)

¿Estoy en lo correcto?


David tiene razón, y aquí están las citas para respaldarlo. En §12.3.2 / 2, el Estándar dice

Una función de conversión puede ser explícita (7.1.2), en cuyo caso solo se considera una conversión definida por el usuario para la inicialización directa (8.5). De lo contrario, las conversiones definidas por el usuario no están restringidas al uso en asignaciones e inicializaciones. [ Ejemplo :

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 }

- ejemplo final ]

¡Algunos lugares donde ocurre esta conversión contextual están en el operando to ! , los operandos a && , y la condición de un if .

Entonces, la inicialización directa puede hacer uso de operadores de conversión explícitos , y en §4 / 3,

Una expresión e puede convertirse implícitamente en un tipo T si y solo si la declaración T t=e; está bien formado, por alguna variable temporal inventada t (8.5). Ciertas construcciones de lenguaje requieren que una expresión se convierta en un valor booleano. Se dice que una expresión e que aparece en dicho contexto se convierte contextualmente a bool y está bien formada si y solo si la declaración bool t(e); está bien formado , por alguna variable temporal inventada t (8.5) ...

Como puede ver, la norma especifica como, si es inicialización directa para las conversiones contextuales, por eso las conversiones explícitas funcionan en las condiciones.


El código es conforme. Se llamará al operador de conversión explícita a bool cuando el objeto se use como condición automáticamente. El cambio en el estándar tenía como objetivo mantener ese mismo uso al tiempo que lo hacía un poco más seguro.


explicit operator bool (y solo explicit operator bool ) tiene un lenguaje especial que le permite ser convertido implícitamente a un bool en ciertas circunstancias. El lenguaje de especificación para esta conversión es "contextualmente convertido a bool ".

Estos son los lugares donde el lenguaje hace pruebas booleanas. La expresión condicional utilizada por un if/while/for es "convertida contextualmente a bool ". Como son los operadores lógicos y el operador condicional ( ?: .

Entonces, si bien no puedes hacer esto:

bool b = std::getline(fin, str); void func(bool) {} func(std::getline(fin, str));

Usted puede hacer esto:

while(std::getline(fin, str)) {...} for(;std::getline(fin, str);) {...} if(std::getline(fin, str) && somethingElse) {...}