Tôi đang cố gắng hiểu cách các liên minh được mở rộng bằng C++ 11. Một điều đã thay đổi là khả năng sử dụng các thành viên dữ liệu không tĩnh với các chức năng thành viên đặc biệt không tầm thường. Từ cppreference.comCông đoàn trong C++ 11: hàm tạo mặc định dường như bị xóa
Nếu một liên minh có chứa một thành viên dữ liệu không tĩnh với một không tầm thường chức năng đặc biệt thành viên (constructor mặc định, sao chép/constructor di chuyển, sao chép/chuyển nhượng di chuyển, hoặc destructor), chức năng đó sẽ bị xóa theo mặc định trong công đoàn và cần được xác định rõ ràng bởi lập trình viên. Tối đa một thành viên dữ liệu có thể có trình khởi tạo thành viên mặc định.
tôi đang cố gắng đoạn mã sau:
struct X
{
~X() {};
};
union U
{
X x;
~U() {};
};
int main()
{
U s1{}; // works, probably aggregate initialization
U s2; // DOES NOT compile, why?
}
Đây X
(được sử dụng như một thành viên dữ liệu của các công đoàn) đã một người dùng cung cấp destructor, vì thế mà destructor của công đoàn theo mặc định bị xóa. Do đó tôi cung cấp một cách rõ ràng. Tuy nhiên, mã thất bại trong việc biên dịch, với các lỗi
lưu ý: 'U :: U()' được mặc nhiên bị xóa vì định nghĩa mặc định sẽ là vô hình thành:
mã biên dịch nếu Tôi xóa dòng cuối cùng U s2;
.
Câu hỏi Điều gì đang xảy ra ở đây? Tại sao biên dịch U s1{};
, nhưng U s2;
thì không? Là ctor mặc định của công đoàn được đánh dấu là đã xóa (nếu có, tại sao ?!), và trong trường hợp đầu tiên chúng ta chỉ cần khởi tạo tổng hợp? Lưu ý rằng nếu tôi cung cấp U(){}; // not U() = default;
mã biên dịch (nhưng không phải nếu tôi chỉ cung cấp một ctor của X
).
EDIT
Sau khi đào sâu vào các tiêu chuẩn (N4527):
đoàn: 9.5/2 [class.union]
[Ghi chú: Nếu bất kỳ không tĩnh thành viên dữ liệu của một công đoàn có một hàm tạo mặc định nhỏ (12.1), sao chép hàm (12.8), di chuyển hàm khởi tạo (12.8), toán tử gán (12.8), di chuyển toán tử gán (12.8), hoặc hàm hủy (12.4). thành viên func tion của công đoàn phải được người dùng cung cấp hoặc nó sẽ bị xóa hoàn toàn (8.4.3) cho công đoàn. —endnote]
có vẻ như đây là lỗi gcc (hiện được báo cáo here). Mã biên dịch trên clang và gcc 4.8.2 hoặc cũ hơn, nó phá vỡ trên gcc4.9 và sau đó (nhờ @ T.C. Để chỉ ra).
Trình biên dịch: g ++ 5.3, -std=c++11
được sử dụng.
[Clang] (http://coliru.stacked-crooked.com/a/b58a360400009fa9) hoàn toàn hài lòng với mã này. Điều này trông giống như một lỗi GCC với tôi, thực sự. –
@ T.C. Có, tôi thực sự đã thấy điều này ngay sau khi nhận xét của bạn. Lần đầu tiên tôi có tiếng kêu ấn tượng cũng đã từ chối nó, có thể đã được thử nghiệm một số phiên bản sửa đổi. Đã chỉnh sửa dòng cuối cùng của câu hỏi, cảm ơn. – vsoftco
@ T.C. Tôi sẽ cố gắng đào sâu vào tiêu chuẩn ... – vsoftco