c++primer学习笔记 函数匹配

在大多数情况下我们容易确定某次调用应该选择哪个重载函数,然而,当几个重载函数的形参数量相等以及某些形参类型可以由其他类型转换而来时,这项工作就不那么容易了:
void f();
void f(int);
void f(int, int);
void f(double,double=3.14);
f(5.6);   //调用void f(double,double)

一 确定候选函数和可行函数
函数匹配的第一步是选择本次调用对应的重载函数集,集合中的函数成为候选函数,
候选函数特征:
1.与被调用的函数同名
2.其声明在调用点可见
在上述例子中,有4个名为f的候选函数。
第二步考察本次调用提供的实参,然后从候选函数中选出能被这组实参调用的函数,这些新选出的函数成为可行函数,
可行函数特征:
1.形参数量与本次调用提供的实参数量相等,而是每个实参的类型与对应的形参类型相同,或者能够转化为形参的类型。
2.每个实参的类型与对应的形参类型相同,或者可以转换成形参的类型
我们能根据实参的数量从候选函数中排除掉两个,无参数和两个int类型参数都不行,而一个int和有默认值的两个double类型是可行的
二 寻找最佳匹配
函数匹配的第三步是从可行函数中选择与本次调用最匹配的函数。在这一过程中,逐一检查函数调用提供的实参
1含有多个形参的函数匹配
如果有多个可行函数,那么编译器依次检查每个实参以确定哪个函数是最佳匹配。如果有且只有一个函数满足下列条件,则匹配成功:

  • 该函数每个实参的匹配都不劣于其他可行函数需要的匹配
  • 至少有一个实参的匹配优于其他可行函数提供的匹配
    若无函数脱颖而出,编译器会报错,认为此为二义性调用

三 实参类型转换
1:精确匹配,包括以下情况:

  • 实参类型和形参类型相同
  • 实参从数组类型或函数类型转换成对应的指针类型
  • 向实参添加顶层const或者从实参中删除顶层const
    2通过const转化成实现的匹配
    3通过类型提升实现的匹配
    4通过算术类型转换或指针转化
    5通过类类型转化实现匹配

3.1需要类型提升和算术类型转化的匹配
一般小整型一般都会提升到int类型或者更大的整数类型。假设有两个函数,一个接收int,一个接收short,则只有当调用提供的是short类型的值时才会选择short版本的函数,有时候,即使实参是很小的整数值,也会直接将它提升为int类型;此时使用short版本反而会导致类型转换:

void ff(int);
void ff(short);
ff('a');          //char 提升成int;调用f(int)
所有算术类型转化的级别都一样,例如int向unsigned int的转换并不比int向double的转换界别高。

考虑:

void manip(long);
void manip(float);
manip(3.14);  //二义性调用

3.14的类型是double,所以既可以转换为long也可以转化为float,因为存在两种可能的算术类型转换,因此该调用具有二义性。
3.2函数匹配与const实参
如果重载函数的区别在于它们引用类型的形参是否引用了const,或者指针类型的形参是否指向const,则当调用发生时编译器通过实参是否为常量来决定那个函数

Record lookup(Account &);
Record lookup(const Account&);
const Account a;
Account b;

lookup(a);//调用Record lookup(Account &);
lookup(b);//调用Record lookup(const Account &);
在第一个调用中,我们传入的是const对象a。因为普通引用不可以绑定到const对象中所以唯一可行的函数就是以常量引用作为形参的那个函数,并且调用该函数与实参a精确匹配。
第二个调用中,两个函数都是可行的,但是非常量对象b初始化常量引用需要进行类型转换,接受非常量形参的版本则与b精确匹配。

四 函数指针
函数指针指向的是函数而非对象。和函数的类型由它的返回类型和形参类型共同决定,与函数名无关。

bool lengthCompare(const string &,const string &);
该函数的类型bool(const string &,const string &);
要想声明一个可以指向该函数的指针,只需要用指针替换函数名即可:
//pf指向一个函数,该函数的参数是两个const string的引用,返回值是bool类型
	bool  (*pf)(const string &,const string &);

pf两端的括号必不可少,如果不写这对括号,则pf是一个返回值为bool指针的函数

使用函数指针
当我们把函数名作为一个值使用时,该函数自动地转化为指针。例如

pf =lengthCompare;
pf =&lengthCompare;//等价的赋值语句,取地址符是可取的
此外,我们还能直接使用指向函数的指针调用该函数,无须提前解引用函数指针:

指向不同函数类型的指针之间不存在转换规则,但我们可以为其赋nullptr或者值为0的整型常量表达式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值