在面對C++模板的時候,需要十分注意,因為模板的復雜性有很多情況,所以最好學習模板的方法我個人認為就是用到就去學,用不到就盡量別去看各種奇門怪技,因為你就算看了,好不容易搞懂模板的實現內部了,包括元編程啊什么的,但真正用到工作中的我相信很少,不久你也會忘掉,所以,對於模板,我們可以采取用到哪學到哪的觀念去學習,這樣可以節省時間並且讓效率最大化。
今天主要講在關於模板特化已經函數重載的問題,簡單舉下例子
1 void say(int value); 2 template <typename T> void say(T value); 3 template<> void say(int value);
如上三個函數,C++默認規定,如果存在非模板函數做到完全匹配(包括const和const &)就優先匹配非模板函數,然后匹配特化模板,然后匹配模板,所以上面的順序是如果我調用say(1) 為 1 > 3 > 2 。注意,在匹配的過程中允許你的普通函數不需要做到所謂的“完全匹配”,可以有一些適當的變化比如:const或者const &,這點很關鍵.
在此我引用百度百科上對於重載的介紹來加深映像印象:
第一步:創建候選 函數列表,其中包含有與被調函數名稱相同的函數與模板函數。第三步:確定是否有最佳可行的 函數。如果有,則使用。
最后,再附上一個比較容易搞混的demo
#include <iostream> using namespace std; template<class T> void func(T &s) { cout << "template version!" << endl; cout << sizeof(s) << ":\t" << s << endl; } void func(const char *s) { cout << "special version!" << endl; cout << sizeof(s) << ":\t" << s << endl; } int main() { char s[] = "asdasdasd"; func(s); return 0; }
這個demo,調用的時候會去調用templation的版本(Windows下的cl默認是進special,我這里用的是gcc)。順便摘錄一個大牛的評論:
原因在於s對於模板函數來說是經歷了一次identity conversion,其rank是Exact Match,普通函數時實參是數組類型,形參是指針類型,所以這里有array-to-pointer conversion和qualification conversions,兩者的rank一樣,最后的轉換rank是Exact Match。然而,僅比較rank,都是一樣,無區別。但是在相同情況下,identity conversion優於非indentity conversion,所以引用綁定的要優於后者.
所以我們可以試着去除const,因為沒有了qualification conversions,這個時候就會優先去調用special的版本了。
參考鏈接: http://baike.baidu.com/view/126530.htm?fr=aladdin
http://bbs.csdn.net/topics/390577993