函数匹配过程:
1.候选函数:选择与函数名同名的所有重载函数集合,包括模板,模板具体化,非模板函数;
2.可行函数:根据函数特征标选择能被这组实参调用的函数
3.寻找最佳匹配:
多个形参的函数匹配:
1.该函数每个实参的匹配都不劣于其他可行函数需要的匹配;
2.该函数至少有一个实参的匹配优于其他可行函数的匹配;
即下限比别人的上限高或相同,且由优势;
最佳匹配规则:
1.非模板函数>模板具体化函数>模板函数;
对于模板函数的类型转换,部分排序规则:将寻求最佳匹配;
2.函数实参形参转换优先级:
a.精确匹配:类型相同,数组类型和函数类型到对应指针类型;向实参添加顶层const,从实参中删除顶层const;
精确匹配允许的:
引用:Type->Type& ,Type&->Type;(最优)
数组,函数到指针:Type[]->Type*,Type()->Type(*),(最优)
const与volatile:Type->const Type;Type->volatile Type,(属于b)
底层const转换:Type*->const Type*;Type*->volatile Type*(属于b)
关于重载引用参数:
左值引用形参与可修改的左值实参匹配,const左值引用与可修改的左值实参以及不可修改的左值实参以及临时实参(右值实参)匹配;右值引用与右值实参匹配;发生重载时编译器将越不用转换越好;即右值实参与const左值引用匹配时将创建临时变量,而与右值引用形参匹配时并不发生,const左值引用与非const左值实参匹配时也会发生(const在静态内存区,会在此区创建变量)因此也有消耗,因此消耗越少越好;
b.通过const转换实现的匹配(非const到const,volatile的转换,其实归纳在第一层里比第一层层次低,因为会在静态区出现消耗):const与非const只适用于指针和引用指向的数据,
void recycle(double blot); void recycle(const double blot);
这两个函数的优先级是相同的,编译时会出现二义性错误;
c.通过类型提升实现的匹配(内置类型小转大):特指整形提升,小整型转换为大整型,或者float转换为double,只有这两种;例如char 到int是提升转换,但char到float是标准转换,long到double也是标准转换;
d.通过算术类型转换(标准转换)和指针转换实现的匹配:前者指标准转换,(char到float,long到double),后者指指针类型的转换,如double*转换为void*,const double*到const void*,整数值0,字面值nullptr转换成任意指针类型,
e.通过类类型转换实现的匹配:类继承层次中的转换
注:转换低意义在于对于内存中相邻空间的读写权限与访问权限:这是危险的;所以不允许随意的转换,但由于类的出现,有时随意转换又是必要的,但为了做出限制,所以出现了四种显式转换符:
static_cast<>(类的转换,也可以用于void*的转换,是必要的,他将赋予指针访问相邻内存空间的能力),
dynamic_cast<>(只允许基类指向派生类),(子类转化为父类)
const_cast<>(底层const到非const的转换),(指针,引用的const非const转换,一般const就不行,因为他是不能转换的)
reinterpret_cast<>(最危险,没有任何限制,也是最担心的);