匹配規則
精確匹配
常量版本匹配
變數提公升
算數/指標轉換
類型別轉換
當我們為函式過載,並呼叫過載後的函式時,編譯器會自動根據引數型別進行匹配與轉換但是此時
容易出現二義性錯誤,函式引數轉換與型別提公升容易混淆,例如當我們同時過載了float、double
版本的函式時,傳入乙個int型實參,就會引起二義性錯誤
常量版本過載與匹配
常量版本不是指const int和int這樣的過載,而是指在底層與上層具有不同const含義的變數,
例如指標,const int*,和int不同,前者指向乙個無法更改的int常量(底層不變),而有時容易
將const int和int *const搞混,後者是頂層不變,即定義的此變數不能改變,在函式過載時,
int * const和int *具有等價的意義。類似const int和int具有等價意義。
1
int a(const int *)
2int a(int *)
3int a(int)
4int a(const int)
5int a(int&)
上面過載的函式3、4、5存在二義性,當我們呼叫a(1)時,編譯器無法確認呼叫哪個,編譯器無法區分
他們形參的區別。
int n=2;
const int* p1=&n;
int *p2=&n;
精確匹配:
a(p1) //呼叫1;
a(p2) //呼叫2
常量版本:非常量->常量,逆過程不可行
當我們注釋掉2時,原本呼叫2的就會呼叫1
a(p2) //呼叫1
變數提公升
變數提公升,僅有以下幾種情況
short, unsigned short, char, unsigned char 提公升為 int
float 提公升為 double
1int a(int)
2int a(double)
精確匹配:
a(1); // 1
a(1.2); // 2
無常量版本匹配(等價)
變數提公升:
char b='b';
unsigned char c='c';
short d=2;
unsigned short e=3;
a(b);a(c);a(d);a(e) // 均呼叫1,變數提公升為 int
float f=1.2
a(f) // 呼叫2, float提公升為double
long long g=123;
a(123) // 編譯錯誤,二義性,long long到int和double屬於算數轉換,兩者優先順序相同。
算數(指標)轉換
當我們在非變數提公升情況下的變數型別變化,均為算數轉換
例如double->int, int->char, long long->int,他們具有等價的優先順序,例如
1、int a(int)
2、int a(double)
long long c=123;
a(123) // 出現錯誤, long long轉換為其他的優先順序相同。
a('a') // 呼叫1,型別提公升 char->int
float d=1.2f;a(f) // 呼叫2,型別提公升 float->double
想要算數轉換,便不能出現匹配等級相同的過載函式,
如果去掉1,則long long->double,反之long long->int
類型別轉換
當我們對類定義有型別轉換函式,或者建構函式定義為非explicit的時候,在最低優先順序匹配的時候
會呼叫類型別轉換:
// 當存在2個及以上算數轉換函式時,可能會出現二義性錯誤
class x;
operator double() const
operator int() const
};int a(int)
int a(double)
int a(long long)
int main()
C 函式過載與函式匹配
c primer 筆記,整理關於函式過載與函式匹配的筆記。void func int a 原函式 void func double a 正確 形參型別不同 void func int a,int b 正確 形參個數不同 int func int a 錯誤 只有返回型別不同 typedef int i...
C 學習 函式過載與匹配
在c 中,函式過載一直是乙個常用且重要的東西,但其中也是有很多坑。實際上,在g 處理函式過載的時候,假設有下面兩個函式 void fun int a,int b void fun int a,char b 很明顯這是兩個過載的函式,c 利用一種叫name mangling的技術,經過編譯器處理後,實...
c 之函式過載 函式匹配
case void f void f int void f int,int void f double,double 3.14 匹配原則 1 其形參數量與本次呼叫提供的實參數量相等 2 每個實參的型別與對應的形參型別相同,或者可以轉換成形參的型別 尋找最佳匹配 1 該函式每個實參的匹配都不劣於其他可...