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:
std::getline(fin, str)
devuelve un objetobasic_ios
, cuya clase tiene una función miembroexplicit operator bool() const;
La clase
basic_ios
no tiene unoperator void*() const;
función miembrooperator 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ónT 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ónbool t(e);
está bien formado , por alguna variable temporal inventadat
(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) {...}