2013-07-22 35 views
9

Minimal mã ví dụ:C++ 11 "Trong lớp khởi tạo" tính năng này không làm việc cho công đoàn

struct B { 
    union U { 
    struct S {} s; 
    int i = 100; 
    } 
    u; 
}; 

Bây giờ nếu chúng ta khai báo một B obj; thì obj.u.i được gán một giá trị rác thay vì 100. Xem số demo here. (Giá trị rác khác nhau dựa trên các cờ tối ưu hóa vv).

Tính năng "Khởi tạo lớp" có hoạt động với công đoàn hay không.

  • Nếu có thì cú pháp chính xác là gì? Hay đây là lỗi g ++?
  • Nếu không thì int i = 100; sẽ làm gì?
+1

+1 Câu hỏi hay. – Nawaz

+2

[clang] (http://coliru.stacked-crooked.com/view?id=6ab1a0f46b2229dfc46dfa6f4f5e3163-6e9f1f680880347f6708b805c806db62) có vẻ hài lòng với mã của bạn. – Praetorian

+0

@Praetorian, Cảm ơn. Tuy nhiên, bạn chưa đặt câu lệnh đầu ra. Vì vậy, đây là chính xác [đầu ra clang] (http://coliru.stacked-crooked.com/view?id=542928082d0e3f7d6edd525a7fcfac44-6e9f1f680880347f6708b805c806db62). – iammilind

Trả lời

3

Điều này giống như lỗi GCC. Tiêu chuẩn nói (9.5p2):

At most one non-static data member of a union may have a brace-or-equal-initializer.

Nếu không, quy tắc sẽ giống như đối với một lớp thông thường.

EDIT: Ngoài ra, 12.6.2p8:

In a non-delegating constructor, if a given non-static data member or base class is not designated by a mem-initializer-id (including the case where there is no mem-initializer-list because the constructor has no ctor-initializer) and the entity is not a virtual base class of an abstract class (10.4), then

  • if the entity is a non-static data member that has a brace-or-equal-initializer, the entity is initialized as specified in 8.5;
  • otherwise, if the entity is a variant member (9.5), no initialization is performed;
  • otherwise, the entity is default-initialized (8.5).

Có lẽ các nhà xây dựng mặc định ngầm được xác định đếm đây. Thành viên i đáp ứng các tiêu chí trong dấu đầu dòng đầu tiên, do đó, nó được khởi tạo như là một thành viên lớp thông thường. Thành viên s khớp với dấu đầu dòng thứ hai, vì vậy nó không được khởi tạo.

+0

Bất kỳ giải pháp nào với mã hiện tại? – iammilind

+0

Nó không biên dịch trên VS 2010 & 2012, thậm chí không phải phiên bản đầu tiên, với lỗi: chỉ các thành viên dữ liệu tích phân const tĩnh có thể được khởi tạo trong một lớp. Hoặc cả hai trình biên dịch đều có lỗi hoặc có gì đó khác ... – neagoegab

+0

@neagoegab Cả hai phiên bản VS đều không hỗ trợ khởi tạo lớp dữ liệu thành viên. [clang] (http://coliru.stacked-crooked.com/view?id=6ab1a0f46b2229dfc46dfa6f4f5e3163-6e9f1f680880347f6708b805c806db62) đang biên dịch mã không có lỗi. – Praetorian

2

Tôi nghĩ nó giống như vậy bởi vì một công đoàn đoàn tụ nhiều hơn một phần tử. Dưới đây là công việc xung quanh cú pháp:

struct B { 
    union U { 
    int i; 
    } 
    u {100}; 
}; 

int main() { 
    B obj; 
    std::cout << "obj.u.i = " << obj.u.i << "\n"; 
} 
+1

Vui lòng ngừng đoán. Đăng câu trả lời mà bạn * biết * và có thể giả sử. – Nawaz

+0

@Nawaz, tôi tin rằng tôi đã hỗ trợ câu trả lời của tôi. Cách khác là tìm nó trong tiêu chuẩn, nhưng lúc đó bạn nhanh hơn tôi: D, nhưng tôi sẽ cập nhật câu trả lời. – neagoegab

+0

Giải pháp này không làm việc với vấn đề thực tế của tôi, chỉ cần thêm 'struct S {} s;' bên trong 'union U' và chương trình cung cấp cho [compiler error] (http://ideone.com/5tS7q9). Tôi đã cập nhật câu hỏi cho phù hợp. – iammilind

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