C++ 重载解析步骤
示例
解决过载的步骤为:
通过名称查找查找候选函数。不合格的调用将执行常规的不合格查询以及依赖于参数的查询(如果适用)。
将候选函数集过滤为一组可行函数。一个可行的函数,在调用该函数的参数与该函数采用的参数之间存在隐式转换序列。
voidf(char); //(1)
voidf(int)=delete;//(2)
voidf(); //(3)
voidf(int&); //(4)
f(4);//1,2是可行的(即使2被删除了!)
//3不可行,因为参数列表不匹配
//4是不可行的,因为我们不能将临时绑定到
// anon-constlvaluereference
选择最佳可行的候选人。一个可行的功能F1比另一个可行的功能更好的功能F2,如果在每个参数的隐式转换序列F1并不比相应的隐式转换序列糟糕F2,和...:
3.1。对于某些参数,该参数中的隐式转换F1顺序比F2或中的该参数的转换顺序更好。
voidf(int); //(1)
voidf(char);//(2)
f(4); //调用(1),转换顺序更好
3.2。在用户定义的转换中,从返回F1到目标类型的标准转换顺序比F2或返回类型的标准转换顺序更好。
structA
{
operatorint();
operatordouble();
}a;
inti=a;//a.operatorint()优于a.operatordouble()和转换
floatf=a;//暧昧
3.3。在直接引用绑定中,F1具有相同引用类型的F2不是,或者
structA
{
operatorX&(); //#1
operatorX&&();//#2
};
Aa;
X&lx=a; //呼叫#1
X&&rx=a;//呼叫#2
3.4。F1不是一个函数模板专业化,但F2是,或
template<classT>voidf(T);//#1
voidf(int); //#2
f(42);//呼叫#2,thenon-template
3.5。F1和F2都是功能模板专长,但是F1比更加专业F2。
template<classT>voidf(T); //#1
template<classT>voidf(T*);//#2
int*p;
f(p);//呼叫#2,morespecialized
这里的顺序很重要。更好的转换顺序检查发生在模板检查与非模板检查之前。这会导致转发参考过载的常见错误:
struct A { A(A const& ); //#1 template <class T> A(T&& ); //#2, not constrained }; A a; A b(a); //呼叫#2! //#1 is not a template but #2 resolves to // A(A& ), which is a less cv-qualified reference than #1 //这使其成为更好的隐式转换序列
如果最后没有一个最佳可行的候选人,那电话就是模棱两可的:
void f(double ) { } void f(float ) { } f(42); //错误:模棱两可