函数重载即同一作用域内的几个函数名字相同但形参列表不同,注意,不允许两个函数除了返回类型外其他所有的要素都相同。
在大多数情况下,我们容易确定某次调用应该选用哪个重载函数,然而,当几个重载函数的形参数量相等以及某些形参可以由其他类型转换得来时,就比较复杂了。函数匹配首先是确定候选函数和可行函数,再寻找最佳匹配。
如果有且只有一个函数满足下列条件,则匹配成功:
1. 该函数每个实参的匹配都不劣于其他可行函数需要的匹配;
2. 至少有一个实参的匹配优于其他可行函数提供的匹配。
如果在检查了所有实参之后,没有任何一个函数脱颖而出,则该调用是错误的,编译器将报告二义性调用的错误。
以下程序是一个验证:
// primer_6_6.cpp : Defines the entry point for the application.
// 函数匹配
#include "stdafx.h"
#include<iostream>
using namespace std;
int main()
{
//定义几个重载函数
void f();
void f(int);
void f(int, int);
void f(double,double = 3.14);
//调用函数
//cout << "f(2.56,42): ";
//f(42,2.56);
cout << "f(42): ";
f(42);
cout << "f(42,0): ";
f(42,0);
cout << "f(2.56,3.14): ";
f(2.56,3.14);
system("pause");
return 0;
}
//定义重载函数
void f()
{
cout << "f()" << endl;
}
void f(int)
{
cout << "f(int)" << endl;
}
void f(int, int)
{
cout << "f(int,int)" << endl;
}
void f(double,double = 3.14)
{
cout << "f(double,double = 3.14)" << endl;
}
程序中首先定义了4个重载函数,这里,函数只是作测试用,因此只输出一条区分语句,其它什么事情都不做。然后以多种方式对函数进行调用,分析并验证哪个函数是最佳匹配,对于调用不合法的,分析其原因。
效果如下:
注意,f(42,2.56); 这句代码是被屏蔽掉的,因为编译器会报错。下面来分析一下为什么调用不合法:
f(42,2.56);中,只考虑第一个实参42时我们发现f(int, int)能精确匹配,要想匹配f(double,double),int类型的实参必须转换成double类型。显然需要内置类型转换的匹配劣于精确匹配,因此就第一个实参来说f(int, int)比f(double,double)更好。接着考虑第二个实参2.56,此时f(double,double)是精确匹配,想要调用f(int, int)必须将2.56从double类型转换成int类型,因此就第二个实参来说,f(double,double)更好。编译器最终将因为这个调用具有二义性而拒绝其请求:因为每个可行函数各自在一个实参上实现了更好的匹配,从整体上无法判断孰优孰劣。即如下错误: