2012-07-03 62 views
34

Có phải C++ 11 cho phép khai báo thành viên dữ liệu không tĩnh là 'tự động' nếu chúng được khởi tạo trong khai báo không? Ví dụ:C++ 11 - khai báo thành viên dữ liệu không tĩnh là 'tự động'

struct S 
{ 
    auto x = 5; // in place of 'int x = 5;', which is definitely allowed 
}; 

GCC 4.7 từ chối mã trên, trong khi chấp nhận int x = 5;.

Giả sử đây không phải là lỗi trình biên dịch mà đúng hơn là tiêu chuẩn thực sự không cho phép, tại sao không? Nó sẽ hữu ích như việc khai báo các biến cục bộ auto.

+4

Nó được phép khai báo một thành viên dữ liệu tĩnh theo cách này, nhưng không phải là thành viên dữ liệu không tĩnh (xem danh sách các phép 'tự động' được phép trong C++ 11 §7.1.6.4). Trên đỉnh đầu của tôi, tôi không thể nghĩ ra một lý do chính đáng tại sao nó bị cấm, mặc dù tôi chắc chắn sẽ coi đây là một sự lạm dụng 'tự động'. –

+0

@JamesMcNellis: Tại sao bạn lại coi đây là lạm dụng 'tự động'? Sự khác nhau giữa việc có một biến với tên kiểu dài/phức tạp (để sử dụng 'tự động' thay vì viết loại của nó) ở phạm vi lớp so với việc có một biến ở phạm vi cục bộ là bao nhiêu? – HighCommander4

+4

Tại phạm vi khối Tôi biết biến được sử dụng như thế nào _used_. Ở phạm vi lớp hoặc phạm vi không gian tên, tôi không nhất thiết phải biết cách biến được sử dụng. Hãy xem xét, ví dụ, tổng quát hơn 'auto x = f (a, b, c);': Tôi phải tìm tất cả các hàm 'f()' và thực hiện độ phân giải quá tải trong đầu để tìm ra loại 'x'. Ít nhất là ở phạm vi địa phương, tôi có thể xem xét những gì đang được thực hiện với 'x' và cố gắng suy ra từ đó loại của nó là gì. 'auto' cực kỳ hữu ích, nhưng nó không nên được sử dụng _everywhere_. –

Trả lời

51

Các quy tắc cho việc cấm các thành viên không tĩnh là trong 7.1.6.4 khoản 4:

Các auto type-specifier cũng có thể được sử dụng trong khai báo một biến trong điều kiện của một tuyên bố lựa chọn (6.4) hoặc tuyên bố lặp lại (6.5), trong loại-specifier-seq trong id kiểu mới hoặc loại-id của biểu thức mới (5.3.4), trong khai báo phạm vi và khai báo a thành viên dữ liệu tĩnh với bộ khởi tạo cú đúp hoặc bằng nhau xuất hiện trong đặc tả thành viên của định nghĩa lớp (9.4.2).

Tôi thấy lý do cho nó là tĩnh here phản ánh cách James McNellis giải thích trong nhận xét.

Một cơ quan quốc gia không thích cho phép trình tự định loại tự động cho không phải là số liệu thống kê. Từ e-mail cho tác giả:

template< class T > 
    struct MyType : T { 
     auto data = func(); 
     static const size_t erm = sizeof(data); 
    }; 

Để xác định bố cục của X, chúng tôi hiện có tra cứu tên 2 giai đoạn và ADL. Lưu ý rằng func có thể là một kiểu hoặc một hàm; nó có thể được tìm thấy trong T, không gian tên của MyType, không gian tên được liên kết của T khi khởi tạo, không gian tên chung, một không gian tên ẩn danh hoặc bất kỳ không gian tên nào tuân theo chỉ thị sử dụng. Với sự cẩn thận, chúng tôi có thể có thể ném một số tra cứu concept_map để may mắn. Tùy thuộc vào thứ tự bao gồm tiêu đề, tôi thậm chí có thể nhận được các kết quả khác nhau cho ADL và phá vỡ Quy tắc Một Định nghĩa - trong đó không bắt buộc phải được chẩn đoán.

Do sự tranh cãi này, các tác giả không còn đề xuất rằng tự động được phép cho các thành viên dữ liệu không tĩnh.

Vì vậy, về cơ bản tùy thuộc vào thứ tự bao gồm tiêu đề, loại data có thể rất khác nhau. Tất nhiên, auto x = 5; sẽ không cần phải phụ thuộc vào tra cứu tên 2 giai đoạn hoặc ADL, tuy nhiên, tôi giả định rằng họ đã biến nó thành quy tắc "mền" vì nếu không, họ sẽ phải thực hiện các quy tắc riêng cho từng trường hợp sử dụng làm cho mọi thứ trở nên phức tạp. Trong cùng một bài báo, tác giả đề xuất loại bỏ hạn chế này, tuy nhiên, dường như đề xuất này đã bị từ chối có thể do lý do trên và cũng như vậy hành vi mong đợi có thể giống nhau bất kể trình khởi tạo là gì.

+5

Cảm ơn bạn đã đào bới điều đó, đó là một lý do thú vị! – HighCommander4

+2

N.B. đề xuất ban đầu cho phép nó là [N2426] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2426.htm) –

+1

@ Jonathanathan Thật sự không có hy vọng để xem chủ đề đó hồi sinh nói cho C + + 20? Có một vài nơi trong mã của tôi sẽ dễ đọc hơn nếu được phép. Chủ yếu là 'auto foo_ = Type {...};', vì vậy trường hợp đó sẽ giúp ích. – akim

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