Kısa cevap
Tüm operatörler +=
, -=
, *=
, /=
, &=
, |=
... aritmetik ve aynı beklenti sağlar:
x &= foo() // We expect foo() be called whatever the value of x
Bununla birlikte, operatörler &&=
ve ||=
mantıklı olacaktır ve bu operatörler hataya açık olabilir çünkü birçok geliştirici foo()
her zaman çağrılmayı bekler x &&= foo()
.
bool x;
// ...
x &&= foo(); // Many developers might be confused
x = x && foo(); // Still confusing but correct
x = x ? foo() : x; // Understandable
x = x ? foo() : false; // Understandable
if (x) x = foo(); // Obvious
Kısayol almak için C / C ++ 'yı gerçekten daha karmaşık hale getirmemiz gerekiyor x = x && foo()
mu?
Gerçekten şifreli ifadeyi daha fazla gizlemek istiyor muyuz x = x && foo()
?
Yoksa anlamlı bir kod yazmak if (x) x = foo();
mı istiyoruz ?
Uzun cevap
Örnek &&=
Eğer &&=
operatör sunulmuştu, sonra bu kodu:
bool ok = true; //becomes false when at least a function returns false
ok &&= f1();
ok &&= f2(); //we may expect f2() is called whatever the f1() returned value
eşdeğerdir:
bool ok = true;
if (ok) ok = f1();
if (ok) ok = f2(); //f2() is called only when f1() returns true
Bu ilk kod hataya açıktır çünkü birçok geliştirici f2()
, f1()
döndürülen değer ne olursa olsun her zaman çağrıldığını düşünür . Sadece döndüğünde aranan bool ok = f1() && f2();
yere yazmak gibidir .f2()
f1()
true
- Geliştirici aslında
f2()
yalnızca f1()
döndüğünde çağrılmak istiyorsa true
, bu nedenle yukarıdaki ikinci kod daha az hataya açıktır.
- Else (geliştirici
f2()
her zaman çağrılmak ister) &=
yeterlidir:
Örnek &=
bool ok = true;
ok &= f1();
ok &= f2(); //f2() always called whatever the f1() returned value
Dahası, derleyicinin yukarıdaki kodu optimize etmesi, aşağıdaki koddan daha kolaydır:
bool ok = true;
if (!f1()) ok = false;
if (!f2()) ok = false; //f2() always called
Karşılaştır &&
ve&
Biz operatörler olmadığını merak edebilir &&
ve &
üzerinde uygulandığında aynı sonucu verir bool
değerler?
Aşağıdaki C ++ kodunu kullanarak kontrol edelim:
#include <iostream>
void test (int testnumber, bool a, bool b)
{
std::cout << testnumber <<") a="<< a <<" and b="<< b <<"\n"
"a && b = "<< (a && b) <<"\n"
"a & b = "<< (a & b) <<"\n"
"======================" "\n";
}
int main ()
{
test (1, true, true);
test (2, true, false);
test (3, false, false);
test (4, false, true);
}
Çıktı:
1) a=1 and b=1
a && b = 1
a & b = 1
======================
2) a=1 and b=0
a && b = 0
a & b = 0
======================
3) a=0 and b=0
a && b = 0
a & b = 0
======================
4) a=0 and b=1
a && b = 0
a & b = 0
======================
Sonuç
Bu nedenle EVET biz yerini alabilir &&
tarafından &
için bool
değerler ;-)
Yani daha iyi kullanmak &=
yerine &&=
. Booleanlar için yararsız olarak
kabul edebiliriz &&=
.
Aynısı ||=
operatör |=
aynı zamanda hataya daha az meyillidir||=
Bir geliştirici , bunun yerine f2()
yalnızca f1()
döndüğünde çağrılmak istiyorsa false
:
bool ok = false;
ok ||= f1();
ok ||= f2(); //f2() is called only when f1() returns false
ok ||= f3(); //f3() is called only when f1() or f2() return false
ok ||= f4(); //f4() is called only when ...
Aşağıdaki daha anlaşılır alternatifi tavsiye ederim:
bool ok = false;
if (!ok) ok = f1();
if (!ok) ok = f2();
if (!ok) ok = f3();
if (!ok) ok = f4();
// no comment required here (code is enough understandable)
veya hepsini tek çizgi stilinde tercih ederseniz :
// this comment is required to explain to developers that
// f2() is called only when f1() returns false, and so on...
bool ok = f1() || f2() || f3() || f4();