候选--->可行--->最佳
候选:
1、与被调用的函数同名。
2、其声明在调用点可见。
可行:
1、其形参数量与本次调用提供的实参数量相等。
2、每个实参的类型与对应的形参类型相同,或者能转换成形参的类型。
最佳:
1、 精确匹配:
l 实参类型和形参类型相同
l 实参从数组类型或函数类型转换成对应的指针类型
l 向实参添加顶层const或者从实参中删除顶层const(也就是说顶层const对匹配无影响)
2、 通过const转换实现的匹配
3、 通过类型提升实现的匹配
4、 通过算术类型转换实现的匹配
5、 通过类类型转换实现的匹配
Record lookup(Account&);
Record lookup(const Account&);
const Account a;
Account b;
lookup(a); //调用Record lookup(const Account&)
lookup(b); //调用Record lookup(Account&)
底层const是能区分最佳与否的,首先不能将普通引用绑定到const对象上。要不然常量将会被普通引用修改。所以lookup(a)只能调用Record lookup(const Account&)。
而lookup(b),两种函数都可调用,然而Record lookup(Account&)精确匹配,
而Record lookup(const Account&)需要将Account转换成const Account,
所以Record lookup(const Account&)更佳。
在以前还没有函数原型的概念的时候,函数调用,实参只做类型提升,小整形一般都会提升到int类型或更大的整数类型。而浮点类型一般提升到double。有了函数原型后,需要进行进一步的处理,提供可能需要的类型转换。
void ff(short);
ff(‘a’); //char被提升到int,再由int隐式类型转换成short。
如果本作用域下还有个void ff(int)函数,那么通过最佳匹配的原则3和原则4,优先调用通过类型提升的匹配,char先会类型提升到int,所以将调用形参为int的版本。