2014-11-09 13 views
37

Nếu bạn nhìn vào ngữ pháp cho *declarator*s in §8/4 bạn sẽ nhận thấy rằng một noptr-declarator có thể được viết như sau (ptr-declarator), có nghĩa là, nó có thể được viết như sau (declarator-id), trong đó xác nhận tờ khai như những người thân trong tiêu đề. Như vấn đề của thực tế mã này biên dịch mà không có một vấn đề:Mục đích của khai báo như int (x); hoặc int (x) = 10;

#include <iostream> 
struct A{ int i;}; 
int (x) = 100; 
A (a) = {2}; 
int main() 
{ 
    std::cout << x << '\n'; 
    std::cout << a.i << '\n'; 
} 

Nhưng mục đích của việc cho phép những ngoặc khi một con trỏ (một mảng hoặc một chức năng) không được tham gia vào việc khai báo là gì?

+13

Có lẽ vì cấm chúng sẽ yêu cầu ngữ pháp phức tạp hơn. –

+0

Đó có thể là một lời giải thích. Tôi không nghĩ về điều này. – Mao

+2

Tương tự, '(42)' là một biểu thức hợp lệ mặc dù dấu ngoặc đơn là không cần thiết. –

Trả lời

52

Thực tế là quy tắc này được áp dụng trong trường hợp của bạn không phải là cố ý: Cuối cùng là là kết quả của việc giữ ngữ pháp đơn giản. Không có khuyến khích để cấm các tuyên bố như của bạn, nhưng có rất nhiều disincentives để phức tạp quy tắc, đặc biệt là nếu những người phức tạp như họ đang có.

Tóm lại, nếu bạn không muốn sử dụng cú pháp không cần thiết bị xáo trộn này, đừng.
C++ hiếm khi buộc bạn viết mã có thể đọc được.

Đáng ngạc nhiên là có những kịch bản trong đó dấu ngoặc đơn có thể tiết kiệm trong ngày, mặc dù:

std::string foo(); 

namespace detail 
{ 
    int foo(long); // Another foo 

    struct Bar 
    { 
     friend std::string ::foo(); // Doesn't compile for obvious reasons. 

     friend std::string (::foo)(); // Voilà! 
    }; 
} 
+0

Bạn không thể giải thích một chút về 'friend std :: string (:: foo)();' khai báo? Chúng ta đã thực sự khai báo và lý do gì? –

+3

@DmitryFucintv: Khai báo muốn khai báo cá thể của 'foo' được khai báo trong dòng đầu tiên là' friend' của struct 'Bar'. Để khai báo một hàm làm bạn, bạn cần đưa ra kiểu trả về và các đối số của nó. Nhưng nói rằng 'friend std :: string foo()' sẽ không hoạt động, vì việc sử dụng không đủ điều kiện, 'foo' bị ẩn bởi 'another'' foo'. Vì vậy, người ta phải đủ điều kiện 'foo' bởi vòng loại toàn cầu' :: '. Nhưng điều đó cho thấy hình thức đầu tiên được hiển thị, mà bị mơ hồ với chỉ định của một (không tồn tại) thành viên của 'std :: string'. Một cặp ngoặc đơn quanh ':: foo' phục vụ để tránh sự mơ hồ –

4

Bạn đang đặt ra câu hỏi sai. Câu hỏi đúng là:

Mục đích của việc không cho phép khai báo như vậy là gì?

Câu trả lời là: không có.

Vì vậy, với cú pháp này được cho phép như là một tác dụng phụ của các quy tắc ở nơi khác, đây là những gì bạn nhận được.

+1

Một lý do để không cho phép khai báo như vậy là hiện tại câu lệnh' T (x); 'là khai báo của một biến' x' của kiểu 'T' , chứ không phải là biểu thức diễn xuất chức năng của 'x' để nhập' T' (được thực hiện hoàn toàn cho các tác dụng phụ của nó), đó là hình thức của nó. – jchl

+0

@jchl: _ "thực hiện hoàn toàn cho các tác dụng phụ của nó" _ Có vấn đề của bạn –

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