2017-06-21 15 views
7

[conv]/4:[expr.unary.op]/9 có vẻ ngụ ý rằng toán tử `!!()` Không thể áp dụng cho loại A bên dưới. Nhưng trình biên dịch không đồng ý với điều đó

Một số cấu trúc ngôn ngữ yêu cầu rằng một biểu thức được chuyển đổi sang một giá trị Boolean. Một biểu e xuất hiện trong một bối cảnh như vậy được cho là là ngữ cảnh chuyển đổi sang bool và nổi hình thành khi và chỉ khi tờ khai bool t(e); nổi hình thành, đối với một số phát minh tạm thời biến t (11.6).

Hãy xem xét đoạn mã bên dưới. Nó không biên dịch, không phải trong clang, GCC hoặc VS.

struct A{ bool operator!() { return true; } }; 
int main(){ 
    A a; 
    bool t(a); 
} 

Như vậy, từ [conv]/4, chúng tôi kết luận rằng loại Akhông ngữ cảnh chuyển đổi sang bool.

[expr.unary.op]/9:

Các toán hạng của toán tử phủ định logic ! là ngữ cảnh chuyển đổi sang bool (khoản 7); giá trị của nó là true nếu toán hạng được chuyển đổi là falsefalse nếu không. Loại kết quả là bool.

sự hiểu biết của tôi về đoạn trên là các toán hạng của toán tử phủ định logic ! phải được theo ngữ cảnh chuyển đổi sang bool. Chúng tôi vừa kết luận rằng loại Akhông phải được chuyển đổi theo ngữ cảnh thành bool. Do đó, từ [expr.unary.op]/9, chúng tôi có thể nói rằng mã sau đây cần không phải là biên dịch. Nhưng nó có, trong clang, GCCVS.

struct A{ bool operator!() { return true; } }; 
int main(){ 
    A a; 
    bool t = !a; 
} 

Tôi đang thiếu gì?

+3

Đó không phải là toán tử phủ định hợp lý, hàm của thành viên đó là toán tử 'A ::!', Là dự đoán của tôi. Tôi tin rằng đây là điều tương tự với toán tử ',', toán tử dấu phẩy có ý nghĩa vốn có ngay cả khi không quá tải, nhưng được xác định rõ khi được cung cấp quá tải –

+0

Thử thay đổi 'bool t (a);' thành 'bool t (! a); 'trong ví dụ đầu tiên của bạn. Như thế nào trình biên dịch có thể đoán nó cần phải áp dụng 'toán tử!'. –

+4

[Khoản \ [expr \] xác định tác động của các toán tử khi áp dụng cho các loại mà chúng không bị quá tải.] (Http://eel.is/c++draft/expr#3.sentence-1) – cpplearner

Trả lời

7

[expr] như một toàn thể áp dụng đối với các nhà khai thác built-in:

khoản [expr] xác định ảnh hưởng của các nhà khai thác khi áp dụng cho các loại mà họ chưa được quá tải.

Định nghĩa trong [expr.unary.op] chỉ đơn giản là định nghĩa của built-inoperator!. Thêm vào đó, [over.match.oper] mô tả làm thế nào để tìm kiếm các nhà khai thác quá tải:

Đối với một nhà điều hành @ unary với một toán hạng của một loại có cv-không đủ tiêu chuẩn phiên bản là T1, [...], ba bộ các chức năng ứng cử viên, thành viên được chỉ định ứng cử viên, ứng cử viên không thành viên và ứng cử viên tích hợp, được xây dựng như sau: [...]

Đối !a, bạn sẽ có hai thí sinh: tình trạng quá tải của bạn A::operator!() và được xây dựng trong quy định tại [over.built]:

Ngoài ra còn tồn tại chức năng điều hành ứng cử viên có dạng

bool operator!(bool); 

Để tích hợp được chọn theo độ phân giải quá tải, loại sẽ phải được chuyển đổi theo ngữ cảnh thành bool& dagger; làm đối số của bạn gợi ý. Tuy nhiên, ứng cử viên này không khả thi - nhưng toán tử thành viên quá tải là.


& dagger;T.C. ở trên đầu trang như thường lệ, chỉ ra cwg issue 1919 cho biết loại chuyển đổi theo ngữ cảnh thành bool vẫn không nên sử dụng mã được gắn sẵn operator! do sự cố từ ngữ. Mặc dù, cả gcc và clang đều cho phép nó (đó là điều tất cả chúng ta muốn xảy ra, có thể).

+0

Nhưng lưu ý [vấn đề cốt lõi 1919] (https://wg21.link/CWG1919). –

+1

@ T.C. Bạn không bao giờ hết ngạc nhiên. Ngoài ra, Johannes dường như đã gửi mọi vấn đề cốt lõi. – Barry

Các vấn đề liên quan