2010-02-03 167 views
9

我有以下的一套模板:模板專業化

//1 
template< typename T > void funcT(T arg) 
{ 
    std::cout<<"1: template< typename T > void funcT(T arg)"; 
} 
//2 
template< typename T > void funcT(T * arg) 
{ 
    std::cout<<"2: template< typename T > void funcT(T * arg)"; 
} 
//3 
template<> void funcT<int>(int arg) 
{ 
    std::cout<<"3: template<> void funcT<int>(int arg)"; 
} 
//4 
template<> void funcT< int * >(int * arg) 
{ 
    std::cout<<"4: template<> void funcT< int *>(int * arg)"; 
} 

//... 

int x1 = 10; 
funcT(x1); 
funcT(&x1); 

是否有人可以解釋爲什麼funcT(x1);調用函數#3和funcT(&x1);調用函數#2,但並不#4如預期?
我已經閱讀過這篇文章http://www.gotw.ca/publications/mill17.htm,其中說「重載決議忽略專門化,僅在基本功能模板上運行」。但根據這個邏輯,funcT(x1);應該調用功能#1而不是#3。我很困惑。

+0

這似乎是相關的:http://www.gotw.ca/publications/mill17.htm – 2010-02-03 22:15:27

+0

我可以給你一本真的很好的書:Addison Wesley - C++模板 - 完整指南 – erick2red 2010-02-03 22:24:32

回答

11

函數#3和#4分別是#1的特化,而不是#1和#2的特化。

這意味着您的編譯器會先選擇#1和#2。當它選擇#1最適合funcT(x1)時,它會選擇專門化#3。對於funcT(& x1),它選擇#2作爲最合適的選項,並且沒有發現專業化。

通過編寫#4作爲

template<> void funcT<>(int * arg) 

它成爲#2專業化,你會得到預期的結果#4呼籲本功能(& X1)。

另一種選擇是簡單地寫

void funcT(int *arg) 

因爲常規的功能總是被選擇,而不是模板版本是否匹配。

+0

對。你可以補充一點,爲了讓#4成爲#2的專門化並獲得「預期」的行爲,它應該寫成'template <> void funcT <>(int * arg)' – 2010-02-03 22:56:33

+0

@ÉricMalenfant:我不確定您的評論或我的編輯是否先到,但無論如何感謝。 – villintehaspam 2010-02-03 23:00:47

+0

爲什麼'template <> void funcT <>(int * arg)'而不是'template <> void funcT (int * arg)'? – sepp2k 2010-02-04 04:19:05