C++ 函数重载解析策略( 二 )

#3 和函数 #5、函数 #6 都是特征标完全匹配的最佳匹配函数,函数 #1 需经隐式提升转换,函数 #2 需经隐式标准转换,由此各函数最佳匹配程度为:(#3, #5, #6) > #1 > #2 。当特征标完全匹配时,又有如下规则:

  • 指向非 const 数据的指针和引用优先与形参为非 const 指针和引用的函数匹配;
  • 优先与非模板函数匹配;
  • 同为模板函数时,优先与较具体的模板函数匹配 。
依此规则,非模板函数 #3#5 最佳匹配程度要高于模板函数 #6,即各函数最佳匹配程度为:(#3, #5) > #6 > #1 > #2 。最终出现了两个最佳匹配函数 #3#5,因此该函数调用失败,编译器将报错 。
//重载第 3 步:确定最佳匹配函数void may(char);//原型#3char may(const char &);//原型#5下面展开来说上述几条完全匹配时的规则 。
第 1 条:指向非 const 数据的指针和引用优先与形参为非 const 指针和引用的函数匹配,这一点需明确,const 和非 const 之间的区别只适用于指针和引用 。下面 4 个函数都与函数调用是完全匹配的:
//函数原型void recycle(int);//原型#1void recycle(const int);//原型#2void recycle(int &);//原型#3void recycle(const int &);//原型#4//函数调用int x = 5;recycle(x);//函数定义...
  • 如果这 4 个函数同时存在,则无法完成重载,编译器会报多义性匹配的错误;
  • 如果只存在函数 #1#2,则无法完成重载,编译器会报重复定义的错误;
  • 如果只存在函数 #1#3,则无法完成重载,编译器会报多义性匹配的错误;
  • 如果只存在函数 #1#4,则无法完成重载,编译器会报多义性匹配的错误;
  • 如果只存在函数 #2#3,则无法完成重载,编译器会报多义性匹配的错误;
  • 如果只存在函数 #2#4,则无法完成重载,编译器会报多义性匹配的错误;
  • 如果只存在函数 #3#4,则函数调用时编译器将会选择 #3
第 2 条:优先与非模板函数匹配,这一点比较简单,当完全匹配的函数中,一个是非模板函数,另一个是模板函数时,非模板函数将优于模板函数,显式具体化、显式实例化、隐式实例化都属于模板函数 。
第 3 条:同为模板函数时,优先与较具体的模板函数匹配,找出最具体的模板的规则被称为函数模板的部分排序规则(partial ordering rules) 。这意味着显式具体化优先于常规模板函数,都为常规模板函数时,编译器优先选择实例化时类型转换更少的那一个 。以下面的程序为例,调用方式 recycle(&ink) 既与模板 #1 匹配,此时 Type 将被解释为 blot *,也与模板 #2 匹配,此时 Type 将被解释为 blot,因此将这两个隐式实例 recycle<blot *>(blot *)recycle<blot>(blot *) 发送到可行函数池中 。在选择最佳匹配函数时,#2 被认为是更具体的,因为它已经显式地指出,函数参数是指向 Type 的指针,相比于 #1,它对类型的要求更加地具体,在生成过程中所需要的转换更少,因此调用方式 recycle(&ink) 实际会匹配版本 #2
//两个常规模板函数template <class Type> void recycle(Type t);//原型#1template <class Type> void recycle(Type * t); //原型#2//调用程序包含如下代码struct blot {int a; char b[10];};blot ink = {25, "spots"};...recycle(&ink);//使用版本#2//函数定义...

经验总结扩展阅读