2011-11-02 32 views
6

Xin chào và chúc bạn một ngày tốt lành.C++: buộc biên dịch mẫu hoàn chỉnh (MSVC/G ++)

Tiếp theo đoạn mã biên dịch trên cl.exe (15.00.30729.01) và mingw-g ++ (4.4.0):

template<typename T> class Test{ 
public: 
    T t; 
    void error(){ 
     int doesNotExist = 6; 
     return doesNotExist;//<---- void function returning result 
    } 
}; 

int main(int argc, char** argv){ 
    Test<int> test; 
    return 0; 
} 

Ngoài ra, trên cl.exe bạn thậm chí có thể nhận được ngay với một cái gì đó như thế này:

template<typename T> class Test{ 
public: 
    T t; 
    void error(){ 
     doesNotExist = 6;//<---- undeclared variable 
     return doesNotExist;//<---- void function returning result 
    } 
}; 

Bây giờ, điều này rõ ràng xảy ra vì trình biên dịch không tạo nội dung cho các phương thức của lớp mẫu cho đến khi ai đó gọi cho họ. Tuy nhiên, điều này có thể gây ra vấn đề khi bạn thiết kế lớp mẫu lớn (vì bạn rất có khả năng quên thêm lời gọi thử vào phương thức mới ở đâu đó).

Câu hỏi đặt ra:
Có một switch trình biên dịch cho g ++ hoặc cl.exe mà sẽ buộc trình biên dịch để xử lý toàn bộ mẫu (do đó, mã đoạn này sẽ kích hoạt lỗi biên dịch)?

Trả lời

11

Nếu bạn muốn kiểm tra mẫu với một vài loại, bạn có thể kích hoạt sự khởi tạo thủ công các loại, như trong:

// at namespace level 
template class Test<int>; 

instantiations Explicit của lớp mẫu tự động kích hoạt instantiation của tất cả các thành viên, trong đó có vẻ là những gì bạn muốn.

Vấn đề thực tế là ngôn ngữ được thiết kế để cho phép rõ ràng hành vi mà bạn muốn tránh. Khi một mẫu lớp được khởi tạo ngầm, trình biên dịch sẽ chỉ khởi tạo các phương thức được sử dụng. Trường hợp sử dụng chính của tính năng này là một số phương pháp có thể áp đặt các yêu cầu khắt khe hơn về loại instantiating so với các phương pháp khác, nếu tất cả các phương thức được khởi tạo luôn là thì mẫu lớp chỉ có thể được sử dụng với các loại đáp ứng các yêu cầu nghiêm ngặt hơn.

Bằng cách cho phép trình biên dịch chỉ khởi tạo các phương thức được sử dụng, mẫu lớp có thể được sử dụng với các loại không đáp ứng tất cả các yêu cầu của tất cả các phương pháp, miễn là chúng đáp ứng các yêu cầu của phương pháp thực sự được sử dụng.

Một ví dụ phổ biến là operator[] trong std::map<> mà đòi hỏi sự value_typemặc định-constructible (operator[] sẽ tạo ra một mới đối tượng mặc định khởi nếu phím không có mặt trong các thùng chứa và trả về một tham chiếu đến nó). Hành vi trong ngôn ngữ cho phép bạn sử dụng std::map trên các loại không phải là cấu hình mặc định miễn là bạn không sử dụng operator[] (hoặc bất kỳ hàm thành viên nào khác áp đặt yêu cầu đó).

+2

Đúng, bản mô tả mẫu rõ ràng là những gì bạn muốn. Xem thêm: http://msdn.microsoft.com/en-us/library/by56e477%28VS.80%29.aspx –

+0

Giải thích tốt về mục đích thực sự không có lỗi trình biên dịch. – iammilind

+0

Ok, nó hoạt động. Tôi chấp nhận câu trả lời của bạn, nhưng nó không thực sự cần thiết để giải thích TẠI SAO nó hoạt động theo cách này (tôi đã biết). Cảm ơn vi đa trả lơi. – SigTerm

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