2012-12-29 55 views
13

On Wikipedia Tôi thấy điều này:Mục đích của Parse Vexing là gì?

A a(A()); 

[này] có thể được disambiguated hoặc là

  1. một định nghĩa biến của lớp [A], lấy một ví dụ mang tính chất của lớp [A ] hoặc

  2. khai báo chức năng cho hàm trả về đối tượng thuộc loại [A] và nhận một đối số đơn lẻ (chưa đặt tên) là một hàm trả về kiểu [A] (và không lấy đầu vào).

Hầu hết các lập trình viên mong đợi đầu tiên, nhưng tiêu chuẩn C++ yêu cầu nó được hiểu là thứ hai.

Nhưng tại sao? Nếu đa số cộng đồng C++ mong đợi hành vi trước đây, tại sao không làm cho nó trở thành tiêu chuẩn? Ngoài ra, cú pháp trên là nhất quán nếu bạn không tính đến sự mơ hồ phân tích cú pháp.

Ai đó có thể vui lòng khai sáng cho tôi không? Tại sao tiêu chuẩn đưa ra yêu cầu này?

+0

Có con trỏ hàm ở đâu? –

+0

Đọc thông báo lỗi - http://ideone.com/12sT80#view_edit_box Không phải là con trỏ hàm của loại 'T (*)()'? –

+0

@templateboy: Thông điệp gây hiểu lầm: trong ngữ cảnh đó 'a' về cơ bản đã bị phân rã thành con trỏ hàm để sử dụng trong biểu thức' a.f', nhưng bản thân khai báo 'a' không liên quan gì đến các con trỏ hàm. –

Trả lời

5

Giả sử MVP không tồn tại.

Bạn khai báo hàm như thế nào?

A foo(); 

sẽ là định nghĩa biến, không phải là khai báo phương pháp. Bạn có giới thiệu một từ khóa mới không? Bạn sẽ có một cú pháp khó xử hơn cho một khai báo hàm? Hoặc có thể bạn thay vì có

A foo; 

định nghĩa một biến và

A foo(); 

khai báo một chức năng?

Ví dụ hơi phức tạp hơn của bạn chỉ phù hợp với mẫu cơ bản này. Nói một cách dễ hiểu là mọi tuyên bố "" thay vì "mọi thứ có thể được hiểu là khai báo, sẽ được hiểu là khai báo trừ khi đó là định nghĩa biến duy nhất, trong trường hợp đó là định nghĩa biến ".

có lẽ không phải là động lực đằng sau nó, nhưng lý do đó là một điều kiện là tốt.

1

Không có lý do cụ thể nào khác ngoài [có thể] trường hợp K-ballo xác định.

Nó chỉ là di sản. Đã có các hình thức xây dựng int x; do đó nó không bao giờ có vẻ như một tiếp cận để yêu cầu T x; khi không có ctor args đang chơi.

Tôi có thể tưởng tượng rằng nếu ngôn ngữ được thiết kế từ đầu ngày hôm nay, thì MVP sẽ không tồn tại ... cùng với một số lượng khác của C++.

Nhớ lại rằng C++ phát triển trong nhiều thập kỷ và, ngay cả bây giờ, chỉ được thiết kế bởi ủy ban (xem thêm: camel).

5

Đây chỉ là một phỏng đoán, nhưng nó có thể là do thực tế rằng với cách tiếp cận đưa cho bạn có thể nhận được cả hai hành vi:

A a(A()); // this is a function declaration 
A a((A())); // this is a variable definition 

Nếu bạn đã thay đổi hành vi của nó là một định nghĩa biến, sau đó khai báo hàm sẽ phức tạp hơn nhiều.

typedef A subfunction_type(); 

A a(A()); // this would be a variable declaration 
A a(subfunction_type); // this would be a function declaration?? 
+1

+1 Đó là một điểm tốt. –

+0

Không hoàn toàn chính xác, 'A a (A()); 'là khai báo hàm. Nó có thể được viết lại thành 'A a (A (*)())', có nghĩa là, một hàm có tên 'a' và trả về một đối tượng kiểu' A' với tham số là một hàm: 'void -> A' . Hãy thử biên dịch nó để kiểm tra đơn giản nhất) – gluk47

3

Tác dụng phụ của ngữ pháp được xác định đệ quy.

Nó không được thiết kế cố ý như vậy. Nó đã được phát hiện và ghi lại là phân tích cú pháp gây tranh cãi nhất.

5

Đối với C++, nó khá đơn giản: vì sự cai trị đã được thực hiện theo cách đó trong C.

Trong C, sự nhập nhằng chỉ phát sinh với một typedef và một số mã khá mơ hồ. Hầu như không ai từng gây ra nó một cách tình cờ - trên thực tế, nó có thể đủ tiêu chuẩn như hiếm trừ mã được thiết kế đặc biệt để chứng minh khả năng. Tuy nhiên, tốt hơn hay tệ hơn, khả năng mơ hồ chỉ có nghĩa là ai đó phải giải quyết nó - và nếu trí nhớ phục vụ, nó không được giải quyết bởi Dennis Ritchie, người quyết định rằng bất cứ điều gì có thể được hiểu là tuyên bố sẽ là tuyên bố, ngay cả khi cũng có một giải thích mơ hồ như một định nghĩa.

C++ đã thêm khả năng sử dụng dấu ngoặc đơn để khởi tạo cũng như các cuộc gọi chức năng dưới dạng nhóm và điều này đã di chuyển sự mơ hồ của anh ấy từ ít người biết đến. Thay đổi nó, tuy nhiên, sẽ có yêu cầu phá vỡ các quy tắc như nó đến từ C. Giải quyết sự mơ hồ cụ thể này như mong đợi nhất, mà không tạo ra một nửa tá hơn mà thậm chí còn đáng ngạc nhiên hơn có lẽ sẽ được khá tầm thường là tốt, trừ khi bạn sẵn sàng vứt bỏ khả năng tương thích với C hoàn toàn.

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