type - char to int c++
Es !! una forma segura de convertir a bool en C++? (17)
[Esta pregunta está relacionada pero no es lo mismo que esta .]
Si trato de usar valores de ciertos tipos como expresiones booleanas, recibo una advertencia. En lugar de suprimir la advertencia, a veces uso el operador ternario ( ?:
:) Para convertir a un bool. El uso de dos operadores no ( !!
) parece hacer lo mismo.
Esto es lo que quiero decir:
typedef long T; // similar warning with void * or double
T t = 0;
bool b = t; // performance warning: forcing ''long'' value to ''bool''
b = t ? true : false; // ok
b = !!t; // any different?
Entonces, ¿la técnica de doble no realmente hace lo mismo? ¿Es más o menos seguro que la técnica ternaria? ¿Es esta técnica igualmente segura con tipos no integrales (por ejemplo, con void *
o double
para T
)?
No estoy preguntando si !!t
es un buen estilo. Me pregunto si es semánticamente diferente de t ? true : false
t ? true : false
!! puede ser compacto, pero creo que es innecesariamente complicado. Es mejor desactivar la advertencia o usar el operador ternario, en mi opinión.
!! solo es útil cuando se usa una expresión booleana de forma aritmética, por ejemplo:
c = 3 + !!extra; //3 or 4
(Cuyo estilo es una discusión diferente.) Cuando todo lo que necesitas es una expresión booleana, ¡la !! es redundante Escritura
bool b = !!extra;
tiene tanto sentido como:
if (!!extra) { ... }
¡¡Realmente odio !! t !!!!!! Apesta a lo peor de C y C ++, la tentación de ser demasiado inteligente a la mitad con tu sintaxis.
bool b (t! = 0); // Es la mejor manera en mi humilde opinión, muestra explícitamente lo que está sucediendo.
¡Cuidadoso!
- Un booleano es acerca de la verdad y la falsedad.
- Un entero es sobre números enteros.
Esos son conceptos muy distintos:
- La verdad y la falsedad se trata de decidir cosas.
- Los números son sobre contar cosas.
Al unir esos conceptos, debe hacerse de forma explícita. Me gusta más la versión de Dima:
b = (t != 0);
Ese código dice claramente: compare dos números y almacene el valor de verdad en un booleano.
Alternativamente, puede hacer esto: bool b = (t != 0)
Desactiva la advertencia.
Escribir para claridad primero; luego perfil; luego optimice la velocidad, cuando sea necesario.
El argumento de! operador y el primer argumento del operador ternario se convierten implícitamente a bool, ¡entonces! y?: son IMO tontas decoraciones redundantes del elenco. Yo voto por
b = (t != 0);
Sin conversiones implícitas
El doble no me parece gracioso y en el código de depuración será muy diferente que en el código optimizado.
Si estás enamorado de! siempre podrías Macro.
#define LONGTOBOOL(x) (!!(x))
(como un lado, el operador ternario es lo que yo prefiero en estos casos)
La comparación a 0 no funciona tan bien. Lo que vuelve, ¿por qué? ¿contra ternario?
class foo { public: explicit operator bool () ; };
foo f;
auto a = f != 0; // invalid operands to binary expression (''foo'' and ''int'')
auto b = f ? true : false; // ok
auto c = !!f; // ok
No usaría:
bool b = !!t;
Esa es la forma menos legible (y por lo tanto la más difícil de mantener)
Los otros dependen de la situación.
Si está convirtiendo para usar en una expresión bool solamente.
bool b = t ? true : false;
if (b)
{
doSomething();
}
Entonces dejaría que el lenguaje lo haga por ti:
if (t)
{
doSomething();
}
Si realmente está almacenando un valor booleano. Entonces primero me pregunto por qué tienes un largo en los primeros lugares que requiere el elenco. Suponiendo que necesita el valor largo y el bool consideraría todo lo siguiente dependiendo de la situación.
bool b = t ? true : false; // Short and too the point.
// But not everybody groks this especially beginners.
bool b = (t != 0); // Gives the exact meaning of what you want to do.
bool b = static_cast<bool>(t); // Implies that t has no semantic meaning
// except as a bool in this context.
Resumen: use lo que le da más significado al contexto en el que se encuentra.
Intenta y haz obvio lo que estás haciendo
Recomiendo nunca suprimir esa advertencia, y nunca usar CA CAST (bool) para suprimirla. Es posible que las conversiones no siempre se llamen como usted supone.
Hay una diferencia entre una expresión que se evalúa como verdadera y una booleana de ese valor.
Ambos !! y ternary take acostumbrarse, pero hará el trabajo de manera similar, si no desea definir tipos internos con conversiones sobrecargadas para bool.
El enfoque de Dima también está bien, ya que asigna el valor de una expresión a un bool.
Recomiendo usar
if (x! = 0)
o
if (x! = NULL)
en lugar de si (x); es más comprensible y legible
Si está preocupado por la advertencia, también puede forzar el lanzamiento: bool b = (bool)t;
Todas las técnicas válidas generarán el mismo código.
Personalmente, desactivo la advertencia para que pueda usar la sintaxis más limpia. Castear a un bool no es algo que me preocupe hacer accidentalmente.
Yo usaría b = (0! = T) - al menos cualquier persona cuerda puede leerlo fácilmente. Si hubiera visto doble dang en el código, estaría bastante sorprendido.
Yo usaría bool b = t y dejaré la advertencia de compilación, comentando la seguridad de esta línea en particular. Deshabilitar la advertencia puede morderte en el trasero en otra parte del código.
Sí, es seguro.
0 se interpreta como falso, todo lo demás es cierto,
por lo tanto! 5 sale como un falso
! 0 sale como verdadero
entonces !! 5 sale como verdadero