C++ 函數重載解析策略( 二 )


//重載第 3 步:確定最佳匹配函數void may(char);//原型#3char may(const char &);//原型#5下面展開來說上述幾條完全匹配時的規則 。
第 1 條:指向非 const 數據的指針和引用優先與形參為非 const 指針和引用的函數匹配,這一點需明確,const 和非 const 之間的區別只適用于指針和引用 。下面 4 個函數都與函數調用是完全匹配的:
//函數原型void recycle(int);//原型#1void recycle(const int);//原型#2void recycle(int &);//原型#3void recycle(const int &);//原型#4//函數調用int x = 5;recycle(x);//函數定義...

  • 如果這 4 個函數同時存在,則無法完成重載,編譯器會報多義性匹配的錯誤;
  • 如果只存在函數 #1#2,則無法完成重載 , 編譯器會報重復定義的錯誤;
  • 如果只存在函數 #1#3,則無法完成重載,編譯器會報多義性匹配的錯誤;
  • 如果只存在函數 #1#4,則無法完成重載,編譯器會報多義性匹配的錯誤;
  • 如果只存在函數 #2#3,則無法完成重載 , 編譯器會報多義性匹配的錯誤;
  • 如果只存在函數 #2#4,則無法完成重載,編譯器會報多義性匹配的錯誤;
  • 如果只存在函數 #3#4,則函數調用時編譯器將會選擇 #3
第 2 條:優先與非模板函數匹配,這一點比較簡單,當完全匹配的函數中,一個是非模板函數,另一個是模板函數時 , 非模板函數將優于模板函數,顯式具體化、顯式實例化、隱式實例化都屬于模板函數 。
第 3 條:同為模板函數時 , 優先與較具體的模板函數匹配,找出最具體的模板的規則被稱為函數模板的部分排序規則(partial ordering rules) 。這意味著顯式具體化優先于常規模板函數,都為常規模板函數時,編譯器優先選擇實例化時類型轉換更少的那一個 。以下面的程序為例 , 調用方式 recycle(&ink) 既與模板 #1 匹配 , 此時 Type 將被解釋為 blot *,也與模板 #2 匹配,此時 Type 將被解釋為 blot,因此將這兩個隱式實例 recycle<blot *>(blot *)recycle<blot>(blot *) 發送到可行函數池中 。在選擇最佳匹配函數時,#2 被認為是更具體的 , 因為它已經顯式地指出,函數參數是指向 Type 的指針,相比于 #1 , 它對類型的要求更加地具體,在生成過程中所需要的轉換更少,因此調用方式 recycle(&ink) 實際會匹配版本 #2 。
//兩個常規模板函數template <class Type> void recycle(Type t);//原型#1template <class Type> void recycle(Type * t); //原型#2//調用程序包含如下代碼struct blot {int a; char b[10];};blot ink = {25, "spots"};...recycle(&ink);//使用版本#2//函數定義...部分排序規則的另一個示例程序如下 , 它與上一個例子有異曲同工之妙 。由于模板 #2 做了特定的假設:數組內容是指針 , 對類型的要求更加地具體,因此在調用時第一個參數若傳入指針數組 pt , 則將實際匹配函數 #2 。
//兩個常規模板函數template <typename T>void ShowArray(T arr[], int n);//原型#1template <typename T>void ShowArray(T * arr[], int n); //原型#2//調用程序包含如下代碼int things[6] = {13, 31, 103, 301, 310, 130};int * pt[3] = {&things[0], &things[2], &things[4]};ShowArray(things, 6);//使用版本#1ShowArray(pt, 3);//使用版本#2//函數定義...將有多個參數的函數調用與有多個參數的原型進行匹配時,編譯器必須考慮所有參數的匹配情況 。如果找到比其他可行函數都合適的函數,則選擇該函數 。一個函數要比其他函數都合適,其所有參數的匹配程度都必須不比其他函數差,同時至少有一個參數的匹配程度比其他函數都高 。
在有些情況下,可通過編寫合適的函數調用,來引導編譯器做出程序員期望的選擇 。如下所示,其中模板函數返回兩個值中較小的一個,非模板函數返回兩個值中絕對值較小的那個 。第一次調用時根據重載解析策略選擇了非模板函數 #2;第二次調用時根據重載解析策略選擇了模板函數 #1double 版本 , 屬于模板函數的隱式實例化;第三次調用的

推薦閱讀