Tôi đang cố triển khai lớp boolean của riêng mình, nhưng không thể sao chép ngữ nghĩa gốc cho & &. Mã giả tạo dưới đây trình bày vấn đề:Lười biếng, quá tải C++ && nhà điều hành?
#include <iostream>>
class MyBool {
public:
bool theValue;
MyBool() {}
MyBool(bool aBool) {theValue = aBool;}
MyBool operator&& (MyBool aBool) {return theValue && aBool.theValue;}
};
bool f1() {std::cout << " First\n"; return false;}
bool f2() {std::cout << " Second\n"; return false;}
int main(int argc, char** argv) {
std::cout << "Native &&\n";
f1() && f2();
std::cout << "Overloaded &&\n";
MyBool(f1()) && MyBool(f2());
return 0;
}
Khi biên dịch và chạy, kết quả là:
Native && First Overloaded && Second First
Nói cách khác, & & trên bools là lười biếng (như bất kỳ C++ lập trình viên mong đợi) nhưng quá tải & & không phải là (như lập trình C++ này ít nhất đã không mong đợi).
Có cách nào để quá tải & & không? Tôi có thể tìm thấy nhiều chương trình đánh giá đầy đủ về lười biếng để cung cấp chức năng giống như Haskell, nhưng chúng dường như hoàn toàn quá mức cần thiết cho trường hợp sử dụng của tôi.
Bằng cách lười biếng, bạn có nghĩa là đoản mạch. Các toán tử bị quá tải không có mạch ngắn. – Rapptz
Vấn đề này là chính xác lý do tại sao nó được khuyến khích không quá tải toán tử '&&'. –
Lưu ý rằng lý do toán tử quá tải không thể đoản mạch là 'MyBool aBool' được truyền vào nó như một tham số. Vì vậy, 'MyBool (f2())' cần phải được tính toán trước khi thực hiện 'toán tử &' sẽ có cơ hội để chạy. Về lý thuyết, bạn có thể viết một toán tử 'operator &&' overload mà RHS là một hàm functor trả về 'MyBool'. Sau đó gọi functor đó chỉ khi LHS đánh giá đúng sự thật. Sau đó, trong C++ 11 người gọi có thể viết một lambda: 'MyBool (f1()) && []() {return MyBool (f2()); } '. Nhưng trong thực tế, không làm điều đó - đánh giá lười biếng là khá xấu xí khi bạn phải xác định rõ ràng nó trên mọi cuộc gọi. –