2012-06-06 26 views
5
struct POD { int i, j; };  
class A { 
    POD m_pod; 
public: 
    A() : m_pod({1,2}) {} // error 
    A() : m_pod(static_cast<POD>({1,2})) {} // error 
    A() : m_pod((POD) {1,2}) {} // ok! 
}; 

Tôi thấy điều này trong mã sản xuất cũ được biên dịch với g++34, cho đến lúc đó tôi không biết tính năng này.
Đây có phải là tính năng cụ thể của g++ không? Nếu không thì, tại sao typecasting cần thiết và đó là quá chỉ cast kiểu C được cho phép?Tại sao việc tạo kiểu chữ kiểu C là bắt buộc trong khi khởi tạo dữ liệu POD trong danh sách khởi tạo?

+0

tôi đoán là '{1,2} 'không phải là một loại POD và một' reinterpret_cast' đang xảy ra. –

Trả lời

4

Cú pháp bạn đang sử dụng không chỉ dành cho danh sách khởi tạo, nó cho bất kỳ khởi tạo các loại lớp nào ngoài khai báo của chúng. Ví dụ:

POD p; 
p = (POD) {1, 2}; 

Đây được gọi là literal hợp chất; chúng được thêm vào C trong C99. Chúng không thực sự được hỗ trợ trong C++; GCC cho phép chúng trong C++ (và C89) dưới dạng extension. C++ 11 adds the syntax:

p = POD({1, 2}); 

Hoặc trong trường hợp của bạn:

A() : m_pod(POD({1,2})) {} 
+0

Tôi cũng không biết rằng GCC cho phép 'POD p; Cú pháp p = (POD) {1, 2}; '. Tất cả các câu trả lời đều tốt; chấp nhận điều này cho các thông tin hữu ích về các phần mở rộng. – iammilind

6

Trên thực tế cú pháp như sau không được phép bởi C++ Standard (cả C++ 03, và C++ 11):

A() : m_pod((POD) {1,2}) {} // ok! 

Kể từ GCC biên dịch này, nó là một phần mở rộng GCC.

Nếu bạn biên dịch nó với -pedantic tùy chọn, nó mang lại cho cảnh báo này:

pod.cpp: 8: 29: cảnh báo: ISO C++ cấm ghép-literals


Trong C++ 11, bạn có thể viết điều này:

A() : m_pod{1,2} {} 

Demo: http://ideone.com/XaO4y

Hoặc đơn giản này:

class A { 
    POD m_pod {1,2}; //in-place initialization 
public: 
    A() {} 
}; 

Ideone không hỗ trợ điều này mặc dù.

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