9.8 重载函数选择规则

    上一节讨论了隐式转换的二义性,实际上,隐式转换和重载函数的选择规则也有着紧密的联系,以代码9.7和代码9.8为例,编译器将显示如下代码。


    complex c1(1.0,2.0),cRes; cRes=c1+5;解释为以下代码。 complex c1(1.0,2.0),cRes; cRes=c1+complex(5,0);

    可如果在complex类中定义了double型的转换函数,问题的答案似乎变得有些模糊。

    ❑方案1:cRes=complex(double(c1)+5,0);

    ❑方案2:cRes=c1+complex(5,0);

    实际上,编译器会选择第1种方案执行,下面将讨论重载函数的选择规则。

    9.8.1 重载解析

    在函数重载的情况下,C++编译器需要一套合理的规则来决定函数调用时使用哪一个函数定义,这个过程称为重载解析(overloading resolution),该过程大致有以下几个步骤。

    1.筛选出参数数目正确的函数定义

    因参数默认值的存在,“数目正确”似乎不太好定义,可解释为“参数数目小于等于函数参数列表中的参数个数,且大于等于函数参数列表中没有默认值的参数个数”。

    2.进一步根据参数类型的对应筛选合适的函数定义

    对应参数的类型应一致,或存在一个隐式转换。这一步筛选后的函数定义都是可执行的版本,下一步是选择最优的过程。

    3.选择最优,确定最佳方案

    通常,从最优到最差的排列顺序如下所示。

    ❑完全匹配,其中常规函数优于模板,关于模板的介绍请参考第12章。

    ❑提升转换,即第2章的整体提升。

    ❑其他转换,除整体提升外的转换。

    ❑用户定义的类型转换,如类定义中定义的转换。

    对运算符重载来说,系统内置类型定义的运算符调用具有更高的优先级,这即是前面举例编译器选择“cRes=complex(double(c1)+5,0);”的原因。