2013-06-12 6 views
5

Trích mẫu có vẻ sai, tại sao (c) được gọi thay vì (b)?Trích mẫu có vẻ sai

#include <iostream> 
using namespace std; 
template<class T> void f(T){cout << "f(T)";}//(a) 
template<> void f<>(int*){cout << "f(int*)";}//(b) 
template<class T> void f(T*){cout << "f(T*)";}//(c) 
//void f(int*){cout <<"POD:f(int*)";}//(d) 

int main(int argc,char*argv[]) 
{ 
    int p = 1; 
    f(&p); 
    cout <<endl; 
    return 0; 
} 

đầu ra:

f(T*)

+7

Xem [tại sao không chuyên chức năng mẫu] (http://www.gotw.ca/publications/mill17.htm). – juanchopanza

+1

@jogojapan Tôi đã thay đổi tiêu đề của bản sao để phản ánh tốt hơn câu hỏi. – juanchopanza

Trả lời

3

Ok, chúng ta hãy thiết lập thẳng những gì chúng ta có đầu tiên.

(a) là mẫu chức năng. (b) là một chuyên môn của mẫu chức năng đó. (c) là một mẫu chức năng khác mà quá tải (a).

Khi bạn viết f(&p) có hai tình trạng quá tải cần xem xét: hai mẫu chức năng, (a) và (c). Trong (c) T* chuyên biệt hơn T trong (a), vì vậy (c) được chọn.

Bây giờ hãy xem xét nhận xét ra (d). Đây không phải là một chuyên môn của mẫu hàm (a), mà là quá tải bổ sung. Để giải quyết cuộc gọi f(&p), hiện tại có ba quá tải cần xem xét. (d) không phải là một mẫu và có int* phù hợp với loại &p, vì vậy nó được chọn trên hai mẫu khác.

+0

(bx) đã có trong mã có tên (d) :) – yuan

+0

@yuan oh. Đôi mắt của tôi chỉ đọc qua các mã nhận xét. Chết tiệt, chúng được đào tạo quá tốt :( –

0

Chuyên môn về mẫu phải sau mẫu. Ở đây, trong trường hợp của bạn, có vẻ như sau:

template<class T> void f(T){cout << "f(T)";}//(a) // Template 1 
template<> void f<>(int*){cout << "f(int*)";}//(b) // Specialization of template 1 
template<class T> void f(T*){cout << "f(T*)";}//(c) // Template 2, conceals template 1 

Do đó, bạn sẽ nhận được mẫu 2 được khởi tạo. toi cách chính xác làm điều đó là:

template<class T> void f(T*){cout << "f(T*)";} // Template 1 
template<class T> void f(T){cout << "f(T)";} // Template 2 
template<> void f<>(int*){cout << "f(int*)";} // Specialization of the template 1 

đầu ra:

f(int*)