2013-06-12 99 views
5

模板演繹似乎錯了,爲什麼(c)被調用而不是(b)?模板演繹看起來不對

#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; 
} 

輸出:

f(T*)

+7

參見[爲什麼不專注函數模板(http://www.gotw.ca/publications/mill17.htm)。 – juanchopanza

+1

@jogojapan爲了更好地反映問題,我更改了副本的標題。 – juanchopanza

回答

3

好吧,讓我們設置直我們所擁有的第一位。 (a)是一個函數模板。 (b)是該函數模板的一個特例。 (c)是另一個重載(a)的函數模板。

當您編寫f(&p)時,需要考慮兩個重載:兩個函數模板(a)和(c)。 (c)T*比(a)中的T更專業,所以(c)被選中。

現在讓我們考慮註釋掉(d)。這不是函數模板(a)的專門化,而是額外的重載。要解決f(&p)調用,現在需要考慮三種重載。 (d)不是模板,並且int*&p的類型匹配,所以它被另外兩個選中。

+0

(bx)已經在代號(d):) – yuan

+0

@元哦。我的眼睛剛剛讀過評論的代碼。該死的,他們訓練得太好了:( –

0

模板專業化必須在模板之後。 在這裏,你的情況下,它看起來像這樣:

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 

因此,你實例化模板2。 正確方法TOI做到這一點是:

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 

輸出:

f(int*)