Was kann ein Grund sein, eine Ganzzahl auf diese Weise in einen Booleschen Wert umzuwandeln?
bool booleanValue = !!integerValue;
statt nur
bool booleanValue = integerValue;
Ich weiß nur, dass in VC ++ 7 Letzteres eine C4800-Warnung verursacht und Ersteres nicht. Gibt es einen anderen Unterschied zwischen den beiden?
Antworten:
Die Probleme mit dem "!!" Redewendung ist, dass es knapp, schwer zu sehen, leicht mit einem Tippfehler zu verwechseln, leicht eines der "!" zu löschen und so weiter. Ich habe es in die Kategorie "Schau, wie süß wir mit C / C ++ sein können" eingeordnet.
Schreiben Sie einfach
bool isNonZero = (integerValue != 0);
... seien Sie klar.quelle
!!
Trick definitiv vorzuziehen .In der
!!
Vergangenheit wurde das Idiom verwendet, um sicherzustellen, dass Ihr Bool tatsächlich einen der beiden Werte enthält, die in einerbool
ähnlichen Variablen erwartet werden, da C und C ++ keinen echtenbool
Typ hatten und wir ihn mitint
s gefälscht haben . Dies ist jetzt bei "echten" weniger ein Problembool
.Aber der Einsatz
!!
ist ein effizientes Mittel zur Dokumentation (sowohl für den Compiler und alle zukünftigen Menschen in Ihrem Code arbeiten) , dass ja, Sie wirklich Guss die Absicht hatte , dassint
zu einbool
.quelle
List<String>
bedeutete, oder||=
.!!
ist eine sehr, sehr tief verwurzelte Sprache im C- und C ++ - Universum. Wenn jemand es nicht weiß, sollte er es lernen - und dann seine eigene begründete Einschätzung darüber abgeben, ob er es verwenden soll.Es wird verwendet, weil die C-Sprache (und einige vorstandardisierte C ++ - Compiler auch) nicht den
bool
Typ hatte, nurint
. Also wurden dieint
s verwendet, um logische Werte darzustellen:0
sollte bedeutenfalse
, und alles andere wartrue
. Der!
Betreiber kehrte1
von0
und zu0
allem anderen zurück. Double!
wurde verwendet, um diese zu invertieren, und es wurde verwendet, um sicherzustellen, dass der Wert gerecht ist0
oder1
von seinem logischen Wert abhängt.In C ++ ist dies seit Einführung eines geeigneten
bool
Typs nicht mehr erforderlich. Aufgrund der Abwärtskompatibilität von C mit C ++ (meistens) können Sie jedoch nicht alle älteren Quellen aktualisieren und sollten dies auch nicht müssen. Aber viele Leute tun es immer noch aus demselben Grund: um ihren Code abwärtskompatibel mit alten Compilern zu bleiben, diebool
s immer noch nicht verstehen .Und das ist die einzig wahre Antwort. Andere Antworten sind irreführend.
quelle
Weil! IntegerValue integerValue == 0 bedeutet und !! integerValue also integerValue! = 0 bedeutet, ein gültiger Ausdruck, der einen Bool zurückgibt. Letzteres ist eine Besetzung mit Informationsverlust.
quelle
Eine weitere Option ist der ternäre Operator, der scheinbar eine Zeile weniger Assembler-Code generiert (in Visual Studio 2005 jedenfalls):
bool ternary_test = ( int_val == 0 ) ? false : true;
welches den Assembler-Code erzeugt:
cmp DWORD PTR _int_val$[ebp], 0 setne al mov BYTE PTR _ternary_test$[ebp], al
Gegen:
bool not_equal_test = ( int_val != 0 );
welches produziert:
xor eax, eax cmp DWORD PTR _int_val$[ebp], 0 setne al mov BYTE PTR _not_equal_test$[ebp], al
Ich weiß, dass es kein großer Unterschied ist, aber ich war neugierig und dachte nur, dass ich meine Erkenntnisse teilen würde.
quelle
Ein Bool kann nur zwei Zustände haben, 0 und 1. Eine Ganzzahl kann einen beliebigen Zustand von -2147483648 bis 2147483647 haben, wobei eine vorzeichenbehaftete 32-Bit-Ganzzahl angenommen wird. Das Unäre! Der Operator gibt 1 aus, wenn der Eingang 0 ist, und gibt 0 aus, wenn der Eingang etwas anderes als 0 ist. Also! 0 = 1 und! 234 = 0. Der zweite! schaltet einfach den Ausgang so, dass 0 zu 1 und 1 zu 0 wird.
Die erste Anweisung garantiert also, dass booleanValue entweder auf 0 oder 1 gesetzt wird und kein anderer Wert, die zweite Anweisung nicht.
quelle
int
->bool
Besetzung. Dies ist genau definiert, und alle Nicht-Null-int
Werte werden intrue
und 0 in konvertiertfalse
. Die Warnung, die VC ++ dort ausgibt, ist eigentlich eine "Leistungswarnung" und hat damit nichts zu tun.!!
ist eine idiomatische Methode zum Konvertierenbool
und funktioniert, um die dumme Warnung des Visual C ++ - Compilers über die angebliche Ineffizienz einer solchen Konvertierung zu beenden.Ich sehe an den anderen Antworten und Kommentaren, dass viele Leute mit der Nützlichkeit dieser Redewendung in der Windows-Programmierung nicht vertraut sind. Das heißt, sie haben keine ernsthafte Windows-Programmierung durchgeführt. Und nehmen Sie blind an, dass das, was ihnen begegnet ist, repräsentativ ist (es ist nicht).
#include <iostream> using namespace std; int main( int argc, char* argv[] ) { bool const b = static_cast< bool >( argc ); (void) argv; (void) b; }
Und mindestens eine Person denkt, wenn ein Anfänger seine Bedeutung nicht erkennt, ist es nicht gut. Nun, das ist dumm. Es gibt eine Menge, die Anfänger nicht erkennen oder verstehen. Den eigenen Code so zu schreiben, dass er von jedem Anfänger verstanden wird, ist nichts für Profis. Nicht einmal für Studenten. Beginnen wir auf dem Weg, Operatoren und Operatorkombinationen auszuschließen, die Anfänger nicht erkennen ... Nun, ich habe nicht die richtigen Worte, um diesem Ansatz eine angemessene Beschreibung zu geben, sorry.
quelle
Die Antwort von user143506 ist richtig, aber für ein mögliches Leistungsproblem habe ich die Möglichkeiten in asm verglichen:
return x;
,return x != 0;
,return !!x;
Und auchreturn boolean_cast<bool>(x)
Ergebnisse in diesem perfekten Satz von asm Anweisungen:Dies wurde für GCC 7.1 und MSVC 19 2017 getestet. (Nur der boolean_converter in MSVC 19 2017 führt zu einer größeren Menge an asm-Code, dies wird jedoch durch Vorlagen und Strukturen verursacht und kann aus Sicht der Leistung vernachlässigt werden, da dies auch der Fall ist Zeilen wie oben angegeben können nur für verschiedene Funktionen mit derselben Laufzeit dupliziert werden.)
Dies bedeutet: Es gibt keinen Leistungsunterschied.
PS: Dieser boolean_cast wurde verwendet:
#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); }
quelle
Kein großer Grund, außer paranoid zu sein oder durch Code zu schreien, dass es ein Idiot ist.
Für den Compiler macht es am Ende keinen Unterschied.
quelle
Ich habe diese Technik der Konvertierung in einen
bool
Datentyp noch nie gemocht - sie riecht falsch!Stattdessen verwenden wir ein handliches Template namens
boolean_cast
gefunden hier . Es ist eine flexible Lösung, die expliziter ist und wie folgt verwendet werden kann:bool IsWindow = boolean_cast< bool >(::IsWindow(hWnd));
quelle