实参类型匹配
精确匹配:
- 实参类型和形参类型相同
- 实参从数组类型或函数类型转换成对应的指针类型
- 通过类型提升实现的匹配
- 通过算术类型转换实现的匹配
- 通过类类型转换实现的匹配
需要类型提升和算术类型转换的匹配
小整型一般会提升到 int 类型或更大的整数类型:
void ff(int); void ff(short); ff('a');//char提升成int,调用ff(int)
所有的算术类型转换的级别都是一样:
void manip(long); void manip(float); manip(3.14);//错误:二义性调用
字面值 3.14 的类型是 double ,它既能转换成 long 也能 转换成 float 。因为存在两种可能的算数类型转换,所以该调用具有二义性。
函数匹配和 const 实参
调用发生时编译器通过实参是否是常量来决定选择哪个函数:
Record lookup(Account&);//函数的参数是Account的引用 Record lookup(const Account&);//函数的参数是一个常量引用 const Account a; Account b; lookup(a);//调用lookup(const Account&) lookup(b);//调用lookup(Account&)
- 第一个调用传入 const 对象a。因为不能把普通引用绑定到 const 对象上,所以唯一可行的函数是以常量引用作为形参的函数,并调用该函数与实参a精确匹配。
- 第二个调用传入非常量b。既可以使用b初始化常量引用也可以用它初始化非常量引用。用非常量对象初始化常量引用需要类型转换,接受非常量形参的版本则与b精确匹配。
两个函数唯一区别是它的指针形参指向常量或非常量,则编译器能通过实参是否是常量决定选用哪个函数:
- 如果实参是指向常量的指针,调用形参是 const* 的函数。
- 如果实参是指向非常量的指针,调用形参是普通指针的函数。