updateone updatemany update nodejs example array c++ integer boolean

c++ - updatemany - update mongodb nodejs



Por que usar !! al convertir int a bool? (10)

Históricamente, el !! Se utilizó la expresión idiomática para asegurar que tu bool contenía realmente uno de los dos valores esperados en una variable tipo bool , porque C y C ++ no tenían un tipo de bool verdadero y lo fingimos con int s. Este es un problema menor ahora con bool s "reales".

¡Pero usando !! es un medio eficiente para documentar (tanto para el compilador como para cualquier persona futura que trabaje en su código) que sí, realmente tenía la intención de convertir ese int a un bool .

¿Cuál puede ser una razón para convertir un número entero en un booleano de esta manera?

bool booleanValue = !!integerValue;

en lugar de simplemente

bool booleanValue = integerValue;

Todo lo que sé es que en VC ++ 7 este último causará una advertencia C4800 y el primero no. ¿Hay alguna otra diferencia entre los dos?


La respuesta de user143506 es correcta, pero para un posible problema de rendimiento comparé las posibilidades en asm:

return x; , return x != 0; , return !!x; e incluso return boolean_cast<bool>(x) da como resultado este conjunto perfecto de instrucciones asm:

test edi/ecx, edi/ecx setne al ret

Esto fue probado para GCC 7.1 y MSVC 19 2017. (Solo el booleano_convertidor en MSVC 19 2017 da como resultado una mayor cantidad de código asm, pero esto es causado por la templatación y las estructuras y puede ser descuidado por un punto de vista del rendimiento, porque el mismo las líneas como se indica arriba pueden duplicarse para diferentes funciones con el mismo tiempo de ejecución).

Esto significa: No hay diferencia de rendimiento.

PD: este boolean_cast fue utilizado:

#define BOOL int // primary template template< class TargetT, class SourceT > struct boolean_converter; // full specialization template< > struct boolean_converter<bool, BOOL> { static bool convert(BOOL b) { return b ? true : false; } }; // Type your code here, or load an example. template< class TargetT, class SourceT > TargetT boolean_cast(SourceT b) { typedef boolean_converter<TargetT, SourceT> converter_t; return converter_t::convert(b); } bool is_non_zero(int x) { return boolean_cast< bool >(x); }


Los problemas con el "!!" idioma es que es escueto, difícil de ver, fácil de confundir con un error tipográfico, fácil de soltar uno de los "!" s, y así sucesivamente. Lo puse en la categoría "mira lo lindo que podemos ser con C / C ++".

Simplemente escriba bool isNonZero = (integerValue != 0); ... ser claro.


No hay una gran razón, excepto ser paranoico o gritar a través del código que es un bool.

para el compilador, al final no hará la diferencia.


Nunca me gustó esta técnica de conversión a un tipo de datos bool : ¡huele mal!

En cambio, estamos usando una plantilla práctica llamada boolean_cast encuentra here . Es una solución flexible que es más explícita en lo que está haciendo y se puede usar de la siguiente manera:

bool IsWindow = boolean_cast< bool >(::IsWindow(hWnd));


Otra opción es el operador ternario que parece generar una línea menos de código ensamblador (de todos modos en Visual Studio 2005):

bool ternary_test = ( int_val == 0 ) ? false : true;

que produce el código de ensamblaje:

cmp DWORD PTR _int_val$[ebp], 0 setne al mov BYTE PTR _ternary_test$[ebp], al

Versus:

bool not_equal_test = ( int_val != 0 );

que produce:

xor eax, eax cmp DWORD PTR _int_val$[ebp], 0 setne al mov BYTE PTR _not_equal_test$[ebp], al

Sé que no es una gran diferencia, pero tenía curiosidad y pensé que compartiría mis hallazgos.


Porque! IntegerValue significa integerValue == 0 y !! integerValue por lo tanto, significa integerValue! = 0, una expresión válida que devuelve un bool. Este último es un elenco con pérdida de información.


Se usa porque el lenguaje C (y algunos compiladores C ++ pre-estándar también) no tenían el tipo bool , solo int . Entonces los int se usaron para representar valores lógicos: se suponía que 0 significaba false , y todo lo demás era true . El ! el operador regresaba 1 de 0 y 0 de todo lo demás. Doble ! se usó para invertirlos, y estaba allí para asegurarse de que el valor sea solo 0 o 1 dependiendo de su valor lógico.

En C ++, desde la introducción de un tipo de bool adecuado, no hay necesidad de hacer eso nunca más. Pero no puedes simplemente actualizar todas las fuentes heredadas, y no deberías hacerlo, debido a la compatibilidad con versiones anteriores de C con C ++ (la mayoría de las veces). Pero muchas personas todavía lo hacen, por la misma razón: para mantener su código compatible con versiones anteriores de compiladores antiguos que aún no entienden los bool .

Y esta es la única respuesta real. Otras respuestas son engañosas.


Un bool solo puede tener dos estados, 0 y 1. Un entero puede tener cualquier estado desde -2147483648 hasta 2147483647 asumiendo un entero de 32 bits con signo. ¡El unario! el operador emite 1 si la entrada es 0 y emite 0 si la entrada es cualquier cosa excepto 0. Entonces! 0 = 1 y! 234 = 0. ¡El segundo! simplemente cambia la salida para que 0 se convierta en 1 y 1 se convierta en 0.

Por lo tanto, la primera declaración garantiza que booleanValue se establecerá igual a 0 o 1 y ningún otro valor, la segunda declaración no.


!! es una forma idiomática de convertir a bool , y funciona para callar los graficos del compilador de Visual C ++ acerca de la supuesta ineficiencia de dicha conversión.

Veo por las otras respuestas y comentarios que muchas personas no están familiarizadas con la utilidad de este modismo en la programación de Windows. Lo que significa que no han hecho ninguna programación seria de Windows. Y asuma ciegamente que lo que han encontrado es representativo (no lo es).

#include <iostream> using namespace std; int main( int argc, char* argv[] ) { bool const b = static_cast< bool >( argc ); (void) argv; (void) b; }

> [d:/dev/test] > cl foo.cpp foo.cpp foo.cpp(6) : warning C4800: ''int'' : forcing value to bool ''true'' or ''false'' (performance warning) [d:/dev/test] > _

Y al menos una persona piensa que si un novato absoluto no reconoce su significado, entonces no es bueno. Bueno, eso es estúpido. Hay muchas cosas que los novatos absolutos no reconocen ni entienden. Escribir el código de uno para que sea entendido por cualquier novato no es algo para profesionales. Ni siquiera para los estudiantes. Empezar en el camino de excluir operadores y combinaciones de operadores que los principiantes no entienden ... Bueno, no tengo las palabras para darle a ese enfoque una descripción apropiada, lo siento.

Saludos y hth.,