Câu trả lời ngắn
Tất cả các nhà khai thác +=
, -=
, *=
, /=
, &=
, |=
... là số học và cung cấp cùng sự mong đợi:
x &= foo() // We expect foo() be called whatever the value of x
Tuy nhiên, các toán tử &&=
và ||=
sẽ hợp lý và các toán tử này có thể dễ bị lỗi vì nhiều nhà phát triển mong đợi foo()
sẽ luôn được gọi 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
Chúng ta có thực sự cần phải làm cho C / C ++ phức tạp hơn nữa để có một lối tắt cho x = x && foo()
không?
Chúng ta có thực sự muốn làm xáo trộn thêm tuyên bố khó hiểu x = x && foo()
không?
Hay chúng ta muốn viết mã có ý nghĩa như thế if (x) x = foo();
nào?
Câu trả lời dài
Ví dụ như &&=
Nếu &&=
toán tử có sẵn, thì mã này:
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
tương đương với:
bool ok = true;
if (ok) ok = f1();
if (ok) ok = f2(); //f2() is called only when f1() returns true
Mã đầu tiên này dễ bị lỗi vì nhiều nhà phát triển sẽ nghĩ f2()
luôn được gọi là bất cứ f1()
giá trị nào được trả về. Nó giống như viết bool ok = f1() && f2();
nơi f2()
chỉ được gọi khi f1()
trở về true
.
- Nếu nhà phát triển thực sự muốn
f2()
được gọi chỉ khi f1()
trả về true
, do đó mã thứ hai ở trên ít bị lỗi hơn.
- Khác (nhà phát triển muốn
f2()
luôn được gọi), &=
là đủ:
Ví dụ như &=
bool ok = true;
ok &= f1();
ok &= f2(); //f2() always called whatever the f1() returned value
Hơn nữa, trình biên dịch dễ dàng tối ưu hóa mã trên này hơn mã bên dưới:
bool ok = true;
if (!f1()) ok = false;
if (!f2()) ok = false; //f2() always called
So sánh &&
và&
Chúng tôi có thể tự hỏi liệu các toán tử &&
và &
cho kết quả tương tự khi áp dụng trên bool
các giá trị?
Hãy kiểm tra bằng mã C ++ sau:
#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);
}
Đầu ra:
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
======================
Phần kết luận
Do đó CÓ, chúng ta có thể thay thế &&
bằng &
các bool
giá trị ;-)
Vì vậy, sử dụng tốt hơn &=
thay vì &&=
.
Chúng ta có thể coi &&=
là vô dụng đối với booleans.
Giống với ||=
Toán tử |=
cũng ít bị lỗi hơn||=
Nếu nhà phát triển muốn f2()
được gọi chỉ khi f1()
trả về false
, thay vì:
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 ...
Tôi khuyên bạn nên thay thế dễ hiểu hơn sau đây:
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)
hoặc nếu bạn thích tất cả trong một kiểu đường :
// 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();