C++ 如何判断所调用的重载函数
函数重载是C++的一个重要特性,但是函数重载后调用哪一个函数往往令人很困惑,参照《C++ Primer》第七章的内容总结如下:
重载确定函数调用的步骤
1、候选函数(candidate function)
1)、仅当形参是引用或指针时,形参是否为const 才有影响
2)、不能基于指针本身是否为const 来实现函数重载
3)、return 的类型不能用于判断重载
2、可行函数
1)、函数形参个数匹配(默认参数也是实参)
2)、类型匹配,包含隐式转换的匹配
3、寻找最佳匹配
1)、精确类型匹配 > 需要转换的匹配
2)、通过类型提升的转换 > 其他标准转换
我还是喜欢用实际的例子来说明问题:
1 #include <iostream> 2 #include <cstdlib> 3 4 /*=================================================================*\ 5 * 6 * 重载确定函数调用的步骤 7 * 8 * 2013/6/5 by 樊列龙 9 * 10 \*=================================================================*/ 11 12 /* 13 * 重载确定函数调用的步骤 14 * 1、候选函数(candidate function) 15 * 1)、仅当形参是引用或指针时,形参是否为const 才有影响 16 * 2)、不能基于指针本身是否为const 来实现函数重载 17 * 3)、return 的类型不能用于判断重载 18 * 2、可行函数 19 * 1)、函数形参个数匹配(默认参数也是实参) 20 * 2)、类型匹配,包含隐式转换的匹配 21 * 3、寻找最佳匹配 22 * 1)、精确类型匹配 > 需要转换的匹配 23 * 2)、通过类型提升的转换 > 其他标准转换 24 */ 25 26 using namespace std; 27 28 29 //////////////////////////////////////////////////// 30 void funA(int &a, int &b) 31 { 32 cout << "调用:funA(int &a, int &b)" << endl; 33 } 34 35 void funA(const int &a, const int &b) 36 { 37 cout << "调用:funA(const int &a, const int &b)" << endl; 38 } 39 40 41 //////////////////////////////////////////////////// 42 void funB(int *a, int *b) 43 { 44 cout << "调用:funB(int *a, int *b)" << endl; 45 } 46 void funB(const int *a, const int *b) 47 { 48 cout << "调用:funB(const int *a, const int *b)" << endl; 49 } 50 51 //////////////////////////////////////////////////// 52 void f() 53 { 54 cout << "调用:void f()" << endl; 55 } 56 57 void f(int ) 58 { 59 cout << "调用:void f(int )" << endl; 60 } 61 62 void f(int , int i = 1 ) 63 { 64 cout << "调用:void f(int , int )" << endl; 65 } 66 67 void f(double, double d = 1.0) 68 { 69 cout << "调用:void f(double, double)" << endl; 70 } 71 72 73 /////////////////////////////////////////////////// 74 void ff(short) 75 { 76 cout << "调用:void ff(short)" << endl; 77 } 78 void ff(int) 79 { 80 cout << "调用:void ff(int)" << endl; 81 } 82 83 /////////////////////////////////////////////////// 84 void fff(long) 85 { 86 cout << "调用:void fff(long)" << endl; 87 } 88 void fff(float) 89 { 90 cout << "调用:void fff(float)" << endl; 91 } 92 93 int main() 94 { 95 int a, b; 96 const int ca = 0; 97 const int cb = 0; 98 99 funA(a,b); // 调用:funA(int &a, int &b) 100 funA(a,cb); // 调用:funA(const int &a, const int &b) 101 funA(ca,cb); // 调用:funA(const int &a, const int &b) 102 103 funB(&a,&b); // 调用:funB(int *a, int *b) 104 funB(&ca,&cb); // 调用:funB(const int *a, const int *b) 105 funB(&a,&cb); // 调用:funB(const int *a, const int *b) 106 107 108 f(5.6); // 调用:void f(double, double) 109 //f(5); // Error: 调用重载的‘f(int)’有歧义 110 //f(5,6.0); // 错误:调用重载的‘f(int, double)’有歧义 111 f(static_cast<double>(5),6.0);// 调用:void f(double, double) 112 f(5,static_cast<int>(6.0)); // 调用:void f(int , int ) 113 114 115 cout << "sizeof(short): " << sizeof(short) << endl; 116 cout << "sizeof(char): " << sizeof(char) << endl; 117 118 ff('a'); // 调用:void ff(int) 119 120 //double 既可以转换为long 也可以转换为 float,有二义性 121 //fff(3.14); // 错误:调用重载的‘fff(double)’有歧义 122 123 return EXIT_SUCCESS; 124 }
执行结果:
1 调用:funA(int &a, int &b) 2 调用:funA(const int &a, const int &b) 3 调用:funA(const int &a, const int &b) 4 调用:funB(int *a, int *b) 5 调用:funB(const int *a, const int *b) 6 调用:funB(const int *a, const int *b) 7 调用:void f(double, double) 8 调用:void f(double, double) 9 调用:void f(int , int ) 10 sizeof(short): 2 11 sizeof(char): 1 12 调用:void ff(int)