程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++普通函數與模板函數以及特化函數重載的優先級問題

C++普通函數與模板函數以及特化函數重載的優先級問題

編輯:C++入門知識

C++普通函數與模板函數以及特化函數重載的優先級問題


在面對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 &,這點很關鍵.   在此我引用百度百科上對於重載的介紹來加深映像印象:   在重載及函數模板重載裡,編譯器選擇函數,要經過以下三步,這個過程稱為重載解析。 第一步:創建候選函數列表,其中包含有與被調函數名稱相同的函數與模板函數。 第二步:使用候選函數列表創建可行函數列表。這些都是參數數目正確的函數。 第三步:確定是否有最佳可行的函數。如果有,則使用。 確定最佳函數,只考慮其特征標,而不考慮返回類型(也無從考慮,但是要是硬想辦法的話,也有,不過沒有必要為了不必要的性能而浪費資源)。確定最佳函數,匹配特征標要依次經過以下判斷:(1)完全匹配(常規函數優於模板;允許無關緊要的轉換)(2)提升匹配(如char和short自動轉換為int)(3)標准轉換(int轉換為char,long轉換為double)(4)用戶自定義的轉換(如類聲明中定義的轉換函數)。 完全允許無關緊要的轉換,這些轉換包括引用,指針與實體之間,數組與指針之間,函數與函數指針之間,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,所以引用綁定的要優於後者.

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved