函數的匹配
- 當重載函數的形參數量相等以及某些形參的類型可以由其他的類型轉化得來的時候,對于函數的匹配就會變得很難
確定候選函數和可行函數
- 函數匹配的第一步就是選定本次調用對應的重載函數集,集合中的函數稱為候選函數。候選函數具有兩個特征:1,與被調用的函數同名;2,聲明在調用點是可見的。
- 第二步,考察本次調用所提供的形參,然后從候選函數中選出能被這組實參調用的函數,這些新的選出的函數叫做可行函數。可行函數具有兩個特征:1,形參變量和本次調用的形參數量相等;2,實參的類型和本次調用的從形參的類型相同,或者是可以轉化成形參類型的實參。
- 注意:如果函數含有默認的實參,那么在調用函數的時候,可能傳入實參的數量看能小于他實際使用的數量
尋找最佳匹配
- 函數匹配的第三步是從可行函數中選擇與本次調用最為接近匹配的函數。原則是:實參類型和形參類型越接近,那么函數匹配的越好
含有多個形參的函數匹配
- 實參的數量越多,匹配的難度越大
- 條件:1,該函數的每一個實參的匹配都不會劣于其他可行的函數需要的匹配;2,至少有一個實參的匹配優于其他函數提供的匹配。
- 調用重載函數的時候應該盡量避免使用強制類型轉換。
6.6.1 實參類型轉換
- 為了確定最佳的匹配,編譯器將實參類型轉化分為幾個等級
- 精確匹配,包括以下幾種情形:1,實參類型和形參類型一致;2,實參從數組類型轉化成對應的指針類型。;3,向實參添加頂層的const或者從實參中刪除頂層的const
- 通過const轉化實現匹配
- 通過類型的提升實現的匹配
- 通過算術類型轉換或者指針轉換實現匹配
- 通過類類型轉換實現的匹配
需要類型的提升和算術類型的轉換的匹配
- 假設有兩個同名的函數,一個接收int類型,一個接收short類型。則只有當調用提供的是short類型,才會去調用shaort版本的函數。因此有的時候,即使是一個很小的整數值,也會將其聲明為int類型;此時使用short版本反而會導致類型的轉換。
- 所有的算術類型的轉換的級別都是一樣的,從int向unsigned int的轉換,并不會比從int 向double轉換級別高。
void manip(long);
void manip(float);
mainip(3.24);//錯誤,二義性調用
函數匹配和const實參
- 如果重載函數的區別在于他們的引用類型的實參是否引用了const,或者指針類型的形參是否指向了const,則當調用發生的時候編譯器通過實參是否是常亮來決定選擇哪個函數。
Record lookup(Account& );// 函數的參數是Account的引用
Record lookup(const Account&);//函數的參數是一個常量的引用
const Account a;
Account b;
lookup(a); //調用Record lookup(const Account& );
lookup(b); //調用Record lookup(Account& );
- 第一個調用中,傳入的是const對象a,因為不可以把普通引用綁定到const對象上,所以此例中唯一可行的函數是以常量引用作為形參的那個函數,并且調用該函數與實參a精確匹配。
- 第二個調用中,傳入的是非常量b,對于這個調用來說,兩個函數都是可行的,既可以使用b初始化常量的引用,也可以用它來初始化非常量的引用。然后,使用非常量對象初始化常量的引用需要類型的轉換,接收非常量形參的版本則和b精確匹配。
- 指針類型的形參也是類似的。唯一的區別在于指針的形參指向的是常量還是非常量。實參指向的是常量的指針,則會調用形參是const*的函數;如果實參是指向非常量的指針,調用形參是普通指針的函數。