2015-12-29 14 views
5

Có hai trường hợp trong đó typedef nhầm lẫn với tôi khi nói đến extern template declarationexplicit template instantiation.sử dụng typedef trong bản mẫu và khai báo mẫu bên ngoài

Để minh họa hai xem dưới 2 đoạn mã ví dụ.

xem xét theo gương (Trường hợp 1):

// suppose following code in some cpp file  
template <typename T> 
    struct example 
{ 
    T value; 
}; 

// valid typedefs 
typedef example<int> int_example; 
typedef example<std::string> string_example; 

// explicit instantiation using above typedefs 
template class int_example; // -> compile time error 
template class string_example; // -> compile time error 

// instead we need to use type names 
template class example<int>; // -> OK 
template class example<std::string>; // -> OK 

// QUESTION 1: Why does this work however? is this valid code? 
typedef std::string type_string; 
template class example<type_string>; 

Tại sao template class example<type_string> làm việc với typedef? và tại sao nó hợp lệ trong khi template class string_example thì không?

Hãy xem xét ví dụ (Trường hợp 2) sau:

// suppose following code is in some header file 
template <typename T> 
struct example 
{ 
    T value; 
}; 

// valid typedefs 
typedef std::string type_string; 
typedef example<type_string> string_example; 

// Explicit instantiation declaration 
// QUESTION 2: Is this valid code? if not why not? 
extern template string_example; // -> at least this compiles, but is it OK? 

Như chất vấn trong các bình luận ở trên, là nó có giá trị sử dụng typedef trong extern template declaration, như trong ví dụ trên, và tại sao điều này biên dịch không giống như Case1 nơi không.

Tôi đã đọc về các trường hợp tương tự nhưng không có câu trả lời chi tiết nào cho trên 2 câu hỏi. xây dựng chi tiết được đánh giá rất nhiều!

Trả lời

2
template class int_example; 

không hợp pháp. Từ C++ 11 Stanard:

14.7.2 Explicit instantiation

2 Cú pháp cho instantiation rõ ràng là:

rõ ràng-instantiation:
extern opttemplate Khai báo

Có hai dạng instantiation rõ ràng: định nghĩa instantiation rõ ràng và khai báo instantiation rõ ràng. Tuyên bố khởi tạo rõ ràng bắt đầu bằng từ khóa extern.

3 Nếu instantiation rõ ràng là dành cho một lớp hoặc thành viên lớp, các xây dựng-type-specifier trong khai bao gồm một đơn giản-template-id.

đơn giản-template-id được quy định tại Mục A.12 Templates như:

đơn giản-template-id:
mẫu tên tuổi<mẫu đối số-list opt>

int_example không được coi là một đơn giản-mẫu-id.
example<int> không đủ điều kiện làm đơn giản-mẫu-id.

Tuy nhiên, bằng logic,

extern template string_example; 

là không hợp pháp hoặc. Tôi không biết nó hoạt động như thế nào cho bạn. Tôi đã nhận được lỗi sau khi tôi đã cố gắng để biên dịch một dòng trong g + + 4.9.3.

socc.cc:15:31: error: expected unqualified-id before ‘;’ token 
extern template string_example; // -> compile time error 
+0

em biết tại sao lớp 'mẫu ví dụ ;' và 'extern lớp mẫu ví dụ ;' làm việc (hoặc nó không với GCC), tôi đang sử dụng MSVC-140 btw và nó hoạt động. cám ơn rất nhiều! – codekiddy

+0

'ví dụ ' đủ điều kiện làm * đơn giản-mẫu-id *. –

+0

cảm ơn, tôi đã thực hiện một số thử nghiệm với GCC và có trường hợp g ++ không xác định các tham chiếu cho các trường hợp như 'example ' nhưng msvc biên dịch tốt, cũng có trường hợp msvc đưa ra cảnh báo chứ không phải g ++, rõ ràng là trường hợp này không được mô tả và cũng không được xác định theo tiêu chuẩn. – codekiddy

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