Gibt es eine "sehr schlechte Sache" , die passieren kann &&=
und ||=
als syntaktischer Zucker für bool foo = foo && bar
und verwendet wurde bool foo = foo || bar
?
c++
boolean-operations
Kache
quelle
quelle
x ||= y
ungefähr gleichwertigx = x ? x : y;
? Mit anderen Worten, "auf y setzen, wenn nicht bereits gesetzt". Das ist wesentlich nützlicher als C oder C ++x ||= y
, das ((bool)y
außer beim Überladen des Operators) "x setzen, wenn nicht bereits gesetzt". Ich bin nicht bestrebt, einen weiteren Operator dafür hinzuzufügen, es scheint ein bisschen schwach. Schreib einfachif (!x) x = (bool)y
. Aber dann verwende ichbool
Variablen nicht genug, um zusätzliche Operatoren zu wollen, die nur für diesen einen Typ wirklich nützlich sind.&&=
oder||=
einfach ist, dass C sie nicht hat. Ich bin mir ziemlich sicher, dass C sie nicht hat, weil die Funktionalität nicht als vorteilhaft genug angesehen wurde.bool foo = foo || bar;
Da die Notation ultra-pedantisch ist, würde sie auch undefiniertes Verhalten hervorrufen, da siefoo
vor der Auswertung von nicht initialisiert wirdfoo || bar
. Natürlich soll dies so etwas seinbool foo = …initialization…; …; foo = foo || bar;
und die Frage gilt dann als gültig.Antworten:
A
bool
darf nurtrue
oderfalse
in C ++ sein. Daher ist die Verwendung von&=
und|=
relativ sicher (obwohl mir die Notation nicht besonders gefällt). Zwar führen sie eher Bitoperationen als logische Operationen aus (und schließen daher nicht kurz), aber diese Bitoperationen folgen einer genau definierten Zuordnung, die den logischen Operationen effektiv entspricht, solange beide Operanden vom Typ sindbool
. 1Im Gegensatz zu dem, was andere hier gesagt haben,
bool
darf a in C ++ niemals einen anderen Wert haben, wie z2
. Wenn Sie diesen Wert a zuweisen,bool
wird ertrue
gemäß Standard konvertiert .Der einzige Weg, um einen ungültigen Wert in a zu bekommen,
bool
ist die Verwendung vonreinterpret_cast
on-Zeigern:Da dieser Code jedoch ohnehin zu undefiniertem Verhalten führt, können wir dieses potenzielle Problem bei der Anpassung von C ++ - Code ignorieren.
1 Zugegeben, dies ist eine ziemlich große Einschränkung, wie Angews Kommentar zeigt:
Der Grund dafür ist, dass
b & 2
eine ganzzahlige Heraufstufung so durchgeführt wird, dass der Ausdruck dann äquivalent zu iststatic_cast<int>(b) & 2
, was zu einem Ergebnis führt0
, das dann wieder in a konvertiert wirdbool
. Es ist also wahr, dass die Existenz eines dieoperator &&=
Typensicherheit verbessern würde.quelle
||
und&&
Verknüpfung, dh das zweite Argument ist kein Operand, wenn der erste Operand isttrue
(bzw.false
für&&
).|
,&
,|=
Und&=
bewertet immer beiden Operanden.&=
für eine linke Seite des Typs zu verwendenbool
, da es durchaus möglich ist, dass die rechte Seite von einem anderen Typ alsbool
(z. B.islower
oder einer anderen C-stdlib-Funktion, die für den wahren Wert ungleich Null zurückgibt) ist. Wenn wir die Hypothese hätten&&=
, würde dies wahrscheinlich die rechte Seite zwingen, zu konvertierenbool
, was&=
nicht der Fall ist. Mit anderen Worten,bool b = true; b &= 2;
ergibtb == false
.&&
und&
haben unterschiedliche Semantik:&&
wird den zweiten Operanden nicht auswerten, wenn der erste Operand istfalse
. dh so etwas wieist sicher, aber
ist nicht, obwohl beide Operanden vom Typ sind
bool
.Gleiches gilt für
&=
und|=
:verhält sich anders als:
quelle
Kurze Antwort
Alle Betreiber
+=
,-=
,*=
,/=
,&=
,|=
... sind arithmetische und bieten gleiche Erwartung:Operatoren
&&=
und||=
wären jedoch logisch, und diese Operatoren könnten fehleranfällig sein, da viele Entwickler erwarten würdenfoo()
, immer aufgerufen zu werdenx &&= foo()
.Müssen wir C / C ++ wirklich noch komplexer machen, um eine Verknüpfung zu erhalten
x = x && foo()
?Wollen wir die kryptische Aussage wirklich mehr verschleiern
x = x && foo()
?Oder wollen wir aussagekräftigen Code schreiben wie
if (x) x = foo();
?Lange Antwort
Beispiel für
&&=
Wenn der
&&=
Operator verfügbar war, dann dieser Code:ist äquivalent zu:
Dieser erste Code ist fehleranfällig, da viele Entwickler glauben, dass er
f2()
immer unabhängig vomf1()
zurückgegebenen Wert aufgerufen wird. Es ist wie beim Schreiben,bool ok = f1() && f2();
wof2()
nur bei derf1()
Rückkehr aufgerufen wirdtrue
.f2()
nur bei derf1()
Rückgabe aufgerufen werden möchte , isttrue
der zweite Code oben weniger fehleranfällig.f2()
immer angerufen werden)&=
ist ausreichend:Beispiel für
&=
Darüber hinaus ist es für den Compiler einfacher, diesen obigen Code zu optimieren als den folgenden:
Vergleiche
&&
und&
Wir fragen uns vielleicht, ob die Operatoren
&&
und&
das gleiche Ergebnisbool
liefern, wenn sie auf Werte angewendet werden.Überprüfen wir dies mit dem folgenden C ++ - Code:
Ausgabe:
Fazit
Daher JA können wir ersetzen
&&
durch&
fürbool
Werte ;-)Also besser nutzen
&=
statt&&=
.Wir können
&&=
für Boolesche als nutzlos betrachten.Gleiches gilt für
||=
Wenn ein Entwickler
f2()
nur bei derf1()
Rückgabe angerufen werden möchtefalse
, anstatt:Ich rate die folgende verständlichere Alternative:
oder wenn Sie alle in einem Linienstil bevorzugen :
quelle
success = success && DoImportantStuff()
if(success) success = DoImportantStuff()
. Wenn die Anweisungsuccess &&= DoImportantStuff()
erlaubt wäre, würden viele Entwickler denken, dass sieDoImportantStuff()
immer unabhängig vom Wert von genannt wirdsuccess
. Hoffe, dies beantwortet, was Sie sich fragen ... Ich habe auch viele Teile meiner Antwort verbessert. Bitte sagen Sie mir, ob meine Antwort jetzt verständlicher ist. (über Ihren Kommentar Zweck) Prost, wir sehen uns ;-)success &&= DoImportantStuff()
erlaubt wäre, würden viele Entwickler denken, dass sieDoImportantStuff()
immer als Wert des Erfolgs bezeichnet wird." Das kann man aber sagenif (success && DoImportantStuff())
. Solange sie sich an die Logik hinter der if-Syntax erinnern, sollten sie keine Probleme damit haben&&=
.f1()
immer bewertet wird,ok &&= f(1)
aber nicht, dass es immer bewertet wirdok = ok && f(1)
. Scheint mir genauso wahrscheinlich.v1 += e2
, das syntaktische Zuckeräquivalentv1 = v1 + e1
für die Variable v1 und den Ausdruck e2 zu sein. Nur eine Kurzschreibweise, das ist alles.