c++ - tesis - tipos de variables en investigacion cientifica
¿Qué hay de malo en declarar una variable dentro de la condición de si? (4)
Quizás me estoy oxidando (he estado escribiendo en Python recientemente).
¿Por qué esto no compila?
if ( (int i=f()) == 0)
sin el ()
alrededor de la int i=f()
obtengo otro error mucho más razonable de que i
no es booleano. ¡Pero es por eso que quería el paréntesis en primer lugar!
Mi conjetura sería que el uso de paréntesis lo convierte en una expresión, y que las declaraciones de declaración no están permitidas en una expresión. ¿Es tan? Y si es así, ¿es una de las peculiaridades de sintaxis de C ++?
Por cierto, en realidad estaba tratando de hacer esto:
if ( (Mymap::iterator it = m.find(name)) != m.end())
return it->second;
Hay un problema con el alcance.
Considera el siguiente código:
if ((int a = foo1()) || (int b = foo2()))
{
bar(b);
}
¿Está b declarado dentro del bloque? ¿Qué pasa si foo1()
devuelve verdadero?
Puede declarar una variable en la sentencia if
en C ++ pero está restringida para ser utilizada con inicialización directa y necesita convertirla a un valor booleano:
if (int i = f()) { ... }
C ++ no tiene nada que pueda describirse como "expresión de declaración", es decir, [sub-] expresiones que declaran una variable.
En realidad, solo busqué la cláusula en el estándar y ambas formas de inicialización son compatibles de acuerdo con 6.4 [stmt.select], párrafo 1:
...
condition:
expression
attribute-specifier-seqopt decl-specifier-seq declarator = initializer-clause
attribute-specifier-seqopt decl-specifier-seq declarator braced-init-list
...
Es decir, también es posible escribir:
if (int i{f()}) { ... }
Obviamente, esto solo funciona en C ++ 2011 porque C ++ 2003 no tiene inicialización de llaves.
Puede declarar una variable en una instrucción if (o en for o while), pero solo en el bloque de paréntesis externo y debe poder convertirse a bool.
Tu conjetura es básicamente correcta, no está permitida porque
(int i = 42;)
no es una declaración válida con inicialización.
Necesitas una línea adicional,
Mymap::iterator it;
if ( (it = m.find(name)) != m.end())
return it->second;
pero entonces es mejor escribir
Mymap::iterator it = m.find(name);
if ( it != m.end() )
return it->second;
Puedes poner la línea de return
después del if
, si realmente quieres que vuelva esta línea, al menos para mí esto no daña la legibilidad, pero otros pueden ver eso diferente.
Si realmente quieres declarar un iterador y usarlo como bool en una condición if
, podrías hacer
if ( struct { int it; operator bool() { return it != m.end; } } s = { m.find(name) } )
return s.it->second;
pero lo consideraría dañino ;-)
Es cierto que no puedes escribir
if ( (int i=f()) == 0)
pero puedes escribir perfectamente
if ( int i=f())
Entonces puede usar el operador &&
para realizar ambas operaciones en una declaración como
if ( int i=1 && (i=f()) == 0)
Debería inicializar con cualquier valor que no sea 0, y debería ser la primera condición si su compilador aplica la evaluación de izquierda a derecha.
Pero desafortunadamente, eso no es aplicable en el caso de los iteradores como lo pide su segundo ejemplo.