函数匹配和实参类型转换
一、函数匹配
当我们有重载函数的时候并且重载函数参数可以通过类型转换得到时,我们需要考虑函数匹配,调用的到底是那个函数。
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
- 类类型转换