2010-09-08 44 views
6

Tôi đang cố gắng tìm ra lý do tại sao ví dụ này không biên dịch. Sự hiểu biết của tôi là nếu một biến tĩnh không được thiết lập rõ ràng thì nó mặc định là 0. Trong năm ví dụ dưới đây, bốn ví dụ này hoạt động như tôi mong đợi, nhưng một biến được nhận xét sẽ không biên dịch.Khởi tạo các thành viên tĩnh của một lớp templated

#include <iostream> 
class Foo 
{ 
public: 
    static int i; 
    static int j; 
}; 
template <int n> 
class Bar 
{ 
public: 
    Bar(int) { } 
    static int i; 
}; 

static int i; 
int Foo::i; 
int Foo::j = 1; 
template <> int Bar<2>::i; 
template <> int Bar<3>::i = 3; 

int main(int argc, char** argv) 
{ 
    std::cout << "i   " << i << std::endl; 
    std::cout << "Foo::i " << Foo::i << std::endl; 
    std::cout << "Foo::j " << Foo::j << std::endl; 
    //std::cout << "Bar<2>::i " << Bar<2>::i << std::endl; // Doesn't compile? 
    std::cout << "Bar<3>::i " << Bar<3>::i << std::endl; 
    return 0; 
} 

Tại sao không int Bar<2>::i làm điều tương tự như int Foo::i hoặc static int i?

Chỉnh sửa: Tôi đã quên thêm mẫu <> vào thanh < 2> và thanh < 3> khai báo. (Không giải quyết được vấn đề, mặc dù vẫn nhận được mối liên kết lỗi)

+3

Bản sao của [khởi tạo thành viên tĩnh cho lớp mẫu chuyên biệt] (http://stackoverflow.com/questions/2342550/static-member-initialization-for-specialized-template-class). –

+0

Lỗi liên kết là gì? – Chubsdad

+0

@Chubsdad: Chắc chắn đó là "Tham chiếu không xác định đối với' Thanh <2> :: i' "hoặc điều gì đó có nghĩa là. Trong mã của OP, 'template <> int Bar <2> :: i;' là một khai báo _nondefining_ (xem bản sao được liên kết cho lời giải thích chi tiết của litb). –

Trả lời

5

Theo quy tắc của tiêu chuẩn C++ hiện tại, chuyên môn template <> int Bar<2>::i; chỉ là tuyên bố và không bao giờ là định nghĩa. Để trở thành định nghĩa, bạn phải chỉ định trình khởi tạo. (Xem quy định tại khoản 14.7.3/15)

Bên cạnh đó, bạn bị mất tích một trường hợp rất phổ biến: định nghĩa của một thành viên tĩnh không chuyên của một mẫu:

template <int n> int Bar<n>::i; 

này cung cấp một định nghĩa cho Bar<N>::i cho N không bằng 2 hoặc 3.

1

Theo dự thảo mới nhất của chuẩn C++ nó nói

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 khai báo 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 phả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]

Vì vậy, những gì bạn đang yêu cầu có thể , nếu trình biên dịch của bạn hỗ trợ nó.

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