今天編程遇到一個問題,使用重載會簡單不少,但是如果輸入類型不在預設的類型中,又會出現問題。使用模板又比較麻煩。
所以突發奇想,模板和普通函數同時使用的時候會怎麼樣?
比如如下代碼:
int type(int){
return 0;
}
template<class T>
int type(T){
return 1;
}
本以爲會報錯,畢竟class T裏是可以包含int的,但是沒想到居然成功了。所以查了查,模板同樣有重載。模板函數與非模板函數同樣可以共存。主要規則如下:
-
當不指定模板參數列表的時候,模板與非模板,優先匹配非模板
就如同上面示例的代碼,當執行如下代碼的時候:cout << type(1) << endl; //0
返回值是0,也就是優先匹配了非模板函數。
-
當指定模板參數列表的時候,模板與非模板,匹配模板
還是上面示例的代碼,當執行如下代碼的時候:cout << type<int>(1) << endl; //1 cout << type<>(1) << endl; //1
返回值是1,也就是匹配了模板函數。也就是說,當我指定模板參數列表的時候,即使列表爲空,也會優先匹配模板函數。
-
模板重載,優先匹配更準確的匹配
對於如下代碼:template<class T> int type<T>{ return 0; } template<class T> int type<T*>{ return 1; }
當我執行:
char *ptr; cout << type(ptr) << endl;
返回值是什麼呢?因爲此時對於模板T,既可以指char,也可以指char*。
答案是,輸出的是1。因爲T*匹配的更精準(模板T匹配到的內容越少的越精準)。 -
特殊情況
對於如下代碼:template<class T> int type<T>{ return 0; } template<class T> int type<T&>{ return 1; }
當我執行:
char ch; cout << type(ch) << endl; cout << type((char&)ch) << endl;
這次,感覺兩個情況似乎一樣精準。那麼會調用哪個呢?
沒錯!答案就是…………報錯;-D
你自己都分不清還能指望編譯器分清楚?不存在的。
另外,調試的時候,當沒有模板函數的時候,還遇見一些重載時基本數據類型的隱式轉換,我也同樣總結一波。
對於char、int、float、double、unsigned char、unsigned int、long long這幾個類型而言:
- 首先,char和unsigned char優先轉換爲int型。其次轉換爲其他類型,但如果多個類型同時存在則會報錯。(其實這裏有點出乎我的意料,首先我以爲char和unsigned char會互相轉換,然後纔是int,其次我以爲unsigned int、long long int會和int同優先級)
- float優先轉換爲double,然後是其他類型。同優先級多個類型同時存在時報錯。
- int、double、unsigned int、long long不分優先級
對於指針和數組:
- 不同類型指針之間可以互相轉換,但是和其他基本類型不能互相轉換。
- char*、char[]可以轉換爲string,但不能反過來。