2012-09-12 24 views
10

gcc 4.5.1, SuSE Linux i686C++ template thành viên tĩnh khởi vấn đề

Giả sử chúng tôi đã mã sau:

template<typename realT> class B 
{ 
public: 
    B() {std::cout << "B()" << std::endl;} 
}; 

template<typename realT> class A 
{ 
public: 
    static B<realT> static_var; 
}; 

template<typename realT> B<realT> A<realT>::static_var; 
template<> B<float> A<float>::static_var; 
template<> B<double> A<double>::static_var; 

int main() 
{ 
    A<float> test; 
    return 0; 
} 

Trong trường hợp này, chúng ta sẽ không có bất kỳ đầu ra trong stdout. Trình biên dịch sẽ không tạo ra mã để khởi phao và chuyên môn đôi của lớp A.

Nhưng .. nếu chúng ta sẽ thay đổi khởi tạo như thế này:

template<> B<float> A<float>::static_var = B<float>(); 
template<> B<double> A<double>::static_var = B<double>(); 

trình biên dịch sẽ tạo ra mã như vậy và chúng tôi sẽ có double "B()" ở đầu ra.

Ai đó có thể giúp tôi hiểu về hành vi như vậy không?

Trả lời

8

n3337 14.7.3/13

Một chuyên môn hóa rõ ràng của một thành viên dữ liệu tĩnh của một mẫu là một định nghĩa nếu việc kê khai bao gồm một initializer ; nếu không, đó là một tuyên bố. [Chú ý: Định nghĩa của một thành viên dữ liệu tĩnh của một mẫu đòi hỏi khởi tạo mặc định phải sử dụng một chuẩn bị tinh thần-init-list:

template<> X Q<int>::x; // declaration 
template<> X Q<int>::x(); // error: declares a function 
template<> X Q<int>::x { };// definition 

- cuối note]

braced-init-listC++11 tính năng, như vậy trong C++03 bạn chỉ có thể sử dụng

template<> X Q<int>::x = ...; 
+0

Cảm ơn câu trả lời của bạn! – Ribtoks

+0

Vậy bạn sẽ làm gì nếu 'x' được khởi tạo bởi hàm tạo mặc định (không có C++ 11)? – VF1