2010-10-14 57 views
13

Trong khi đọc this, tôi đang bối rối bởi các ví dụ sau:Chức năng mẫu chuyên môn

// Example 2: Explicit specialization 
// 
template<class T> // (a) a base template 
void f(T); 

template<class T> // (b) a second base template, overloads (a) 
void f(T*);  //  (function templates can't be partially 
        //  specialized; they overload instead) 

template<>  // (c) explicit specialization of (b) 
void f<>(int*); 

// ... 

int *p; 
f(p);   // calls (c) 

Ở đây, (c) là một chuyên môn hóa rõ ràng của (b).

// Example 3: The Dimov/Abrahams Example 
// 
template<class T> // (a) same old base template as before 
void f(T); 

template<>  // (c) explicit specialization, this time of (a) 
void f<>(int*); 

template<class T> // (b) a second base template, overloads (a) 
void f(T*); 

// ... 

int *p; 
f(p);   // calls (b)! overload resolution ignores 
        // specializations and operates on the base 
        // function templates only 

Đây (c) là chuyên môn rõ ràng về (a). Tại sao vậy? Đây có phải là do thứ tự khai báo không?

+1

Ngoại ý Tôi chỉ muốn nói "có" và giả sử mã hợp lệ là câu trả lời duy nhất có thể. Nhưng câu hỏi đặt ra là liệu mã thứ hai có hợp lệ hay không. Tôi tin rằng nó là hợp lệ, nhưng việc tìm kiếm điều này trong tiêu chuẩn có thể là nhiều công việc ... –

+0

@Alf P. Steinbach: tại sao mã thứ hai không thể hợp lệ? – Donotalo

+0

@Donato: bỏ qua các tác giả (những người thực sự (TM) biết nội dung của họ khi nói đến các mẫu) Tôi chỉ cảnh giác với mã có phụ thuộc vào thứ tự hoặc hiệu ứng "tùy ý" khác. Tiêu chuẩn được thiết kế để bảo vệ chống lại những thứ như vậy, để wit, biên dịch hai pha của các mẫu bảo vệ chống lại loại điều đó. Vì vậy, tôi chỉ có một <0.5% cảm giác rằng chỉ có thể có một số quy tắc về nó, sau đó có thể là một trong đó không yêu cầu bất kỳ chẩn đoán. –

Trả lời

11

Có, đó là do thứ tự khai báo. Khi trình biên dịch gặp (c) trong tập thứ hai, mẫu được chỉ định duy nhất để chuyên là (a).

Đây là lý do tại sao bạn phải cẩn thận khi đặt hàng các chuyên môn về mẫu của mình.

Ngôn ngữ lập trình C++ đi sâu vào một số chi tiết về điều này (Mục 13.5.1). Tôi khuyên bạn nên nó.

10

Đó là thứ tự nhưng không phải là chỉ đơn đặt hàng. Đối với mã đầu tiên, cả hai mẫu đã được xác định trước đó. Nhưng thứ hai đã được thực hiện.

Điều này là do hai mẫu được so sánh và thấy rằng (T) khớp với bất kỳ loại nào phù hợp với (T*), nhưng (T*) không khớp với tất cả các loại phù hợp với (T). Do đó, mẫu thứ hai là chuyên biệt hơn. Bất cứ khi nào bạn đặt chuyên môn rõ ràng và hai mẫu đó khớp nhau, các mẫu được so sánh và mẫu được chuyên biệt hóa hơn được liên kết theo chuyên môn rõ ràng. So sánh này được gọi là "đặt hàng một phần".

8

Tiêu chuẩn phải nói như sau về vị trí tương đối của các khai báo chuyên môn rõ ràng. [Mục 14.7.3]

Các vị trí của tờ khai chuyên môn hóa rõ ràng cho chức năng mẫu, các mẫu lớp, hàm thành viên của lớp mẫu, dữ liệu tĩnh thành viên của lớp mẫu, các lớp học viên của các lớp mẫu, lớp thành viên mẫu của lớp mẫu , các hàm thành viên của các mẫu lớp, các hàm thành viên của các mẫu thành viên của các mẫu lớp, các hàm thành viên của các mẫu thành viên của các lớp không mẫu, mẫu chức năng thành viên của các lớp thành viên của các mẫu lớp, v.v. các mẫu lớp, các mẫu lớp thành viên của các lớp không phải mẫu, các mẫu lớp thành viên của các mẫu lớp, v.v., có thể ảnh hưởng đến việc một chương trình có được định dạng đúng theo vị trí tương đối của các khai báo chuyên môn rõ ràng và các điểm diễn giải của chúng trong đơn vị dịch như đã nêu ở trên và bên dưới hay không. Khi viết chuyên môn, hãy cẩn thận về vị trí của nó; hoặc để làm cho nó biên dịch sẽ là một thử nghiệm như để kindle tự thiêu của nó.

+1

+1 cho ** tự thiêu ** - đủ để xua đuổi neophytes tìm cách học C++ – kfmfe04

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