C++

函数重载及其匹配顺序

Posted by DEVIN on Sun, Jun 18, 2023

1.函数重载

概念:同一个作用域内,同名函数,参数列表不同(参数个数、类型或顺序不同)。

  • 与返回值类型没有关系。如果函数名和参数列表相同,无论返回值类型是否相同,会编译错误(函数重定义)
  • const是有效的重载。
  • 仅默认参数值不同不是有效的重载。例如
1int fun(int a = 0);
2// void fun(int a = 1); // error: functions that differ only in their return type cannot be overloaded
  • virutal是无效的重载。virtual关键字可有可无,不影响是否是重载函数。

2.函数重载匹配顺序

编译器根据最佳匹配确定调用哪个函数。C++ 编译器遵循以下先后顺序:

  • 先找参数完全匹配的普通函数(非由模板实例化得到的函数)。
  • 再找参数完全匹配的模板函数
  • 再找实参经过自动类型转换后能够匹配的普通函数。
  • 如果上面的都找不到,则报错。
 1template <class T>
 2void fun(T x, T y) { cout << "fun1" << endl; }
 3
 4template <class T1, class T2>
 5void fun(T1 x, T2 y) { cout << "fun2" << endl; }
 6
 7void fun(int x, int y, int z = 0) { cout << "fun3" << endl; }
 8void fun(char x, char y) { cout << "fun4" << endl; }
 9
10int main()
11{
12    int i1=2, i2=3, i3=5;
13    char c1='a', c2='c', c3='d';
14    double f1=2.45, f2=5.68;
15
16    fun(i1, i2);     // fun3
17    fun(f1, f2);     // fun1
18    fun(i1, f1);     // fun2
19    fun(i1, i2, i3); // fun3
20    fun(c1, c2);     // fun4
21}

当使用具有默认形参值的函数重载形式时,需要注意防止二义性,例如:

 1void fun(int x, int y, int z = 0) { cout << "fun1" << endl; }
 2int  fun(int x, int y)            { cout << "fun2" << endl; return 0; } // 不报错,但是函数调用容易导致二义性
 3//int fun(int x, int y, int z) { return 0; } // 报错,不是有效的重载(即使返回值和第3个参数不同)
 4
 5int main()
 6{
 7    int i1=2, i2=3, i3=5;
 8
 9    fun(i1, i2, i3); // fun1
10//    fun(i1, i2);     // 报错,二义性。无法确定调用哪个函数
11}