一、函式匹配
當我們有過載函式的時候並且過載函式引數可以透過型別轉換得到時,我們需要考慮函式匹配,呼叫的到底是那個函式。
void f();
void f(int);
void f(int, int);
void f(double, double = 3.14);
f(5.6); //呼叫f(double,double);
1、函式匹配過程
- 選擇呼叫哪個過載函式集。
呼叫f(); - 考察本次呼叫函式提供的實參。
f(int, int); //引數數量不匹配
f(int); //double可以轉變為int型別
f(double, double); //第二個引數提供了預設值,第一個引數正好是double,也可以
- 如果存在,那麼從可行函式中選擇與本次呼叫最匹配的函式。
f(double, double); //最匹配的函式
2、特殊情況:含有多個形參
void f();
void f(int);
void f(int, int);
void f(double, double = 3.14);
f(42, 3.14);
此時我們不清楚到底是呼叫f(int, int) 還是呼叫f(double, double = 3.14);
如果只考慮第一個實參,那麼呼叫第一個。
如果只考慮第二個實參,那麼呼叫第二個。
編譯器發現呼叫出現二義性,發現該呼叫是錯誤的。
二、實參型別轉換
編譯器將實參型別轉換劃分為幾個等級,具體排列如下:
- 精準匹配
- 實參型別和形參型別相同。
- 實參從陣列型別或函式型別轉換成對應的指標型別。
- 向實參中新增頂層const或者從實參中刪除頂層const。
- const轉換
int fun(const int);
int a = 10;
const int b = 20;
fun(a); //int型別自動轉換為const int型別
return 0;
int fun(const int *a);
int main()
{
int a = 10;
int *b = &a;
fun(b); //b從int *轉換為const int*型別
}
- 型別提升
void f(int);
void f(short);
f('a'); //char型別轉換為int,呼叫第一個
- 算數型別轉換,指標轉換
void f(long);
void f(float);
f(3.14); //出現二義性,double既能轉換為long,又能轉換為float
- 類型別轉換