王朝网络
分享
 
 
 

Guru of the Week 条款27:转呼叫函数

王朝vc·作者佚名  2006-01-08
宽屏版  字体: |||超大  

GotW#27 转呼叫函数(Forwarding Functions)

难度:3 / 10

怎样将转呼叫函数写得最好?原本答案很简单,但我们已经知道C++语言近来发生了微妙的变化。

问题

转呼叫函数对于将任务传递给其它函数或对象时很有用,尤其当它们被设计得很高效时。

评论一下下面这个转呼叫函数。你试图修改它吗?如果是的话,怎么来?

// file f.cpp

#include "f.h"

/*...*/

bool f( X x ) {

return g( x );

}

(说明:本次GotW的目的之一是阐明在July [1997]于London加入到C++语言中的一个微妙改进所造成的后果。)

解答

转呼叫函数对于将任务传递给其它函数或对象时很有用,尤其当它们被设计得很高效时。

关键点是:效率。

评论一下下面这个转呼叫函数。你试图修改它吗?如果是的话,怎么来?

// file f.cpp

#include "f.h"

/*...*/

bool f( X x ) {

return g( x );

}

有两个主要改进可使得这个函数更高效。第一个应该总被采用,第二个需要权衡。

1.传参时使用传const的引用代替传值

“这不会造成混乱吗?”你可能会问。不,它不会,至少在这种情况下。直到最近,C++语言才规定:因为编译器可以确保参数x除了被传递给g()外没有被其它地方使用,编译器可以将x完全优化掉。例如,这样的代码:

X my_x;

f( my_x );

编译器可以:

a)产生一个my_x的拷贝供f()使用(就是f()的代码体中的形参x),然后将这个拷贝传给g();或者

b)直接将my_x传给g()而不生成拷贝,因为它注意到这个额外的拷贝除了作g()的参数外根本没被使用。

后者更高效,不是吗?这是编译器试图作的优化,不是吗?

是的,是的,但只到July 1997的London会议。在那次会议上,“限制编译器作这种取消额外拷贝的优化”的提案得到了更多的支持。〖注1〗编译器唯一可以取消额外拷贝构造的地方是“返回值优化”(在你的C++宝典中查询细节吧)和“临时对象”。

这意味着,象f这样的转呼叫函数,编译器被要求产生两份拷贝。既然我们(作为f的作者)知道这个额外的拷贝不是必须的,我们应该按照通常的办法将x申明为const X&型的参数。

(注意:如果我们一直就是这么做的,而不是依赖于知道编译器被允许做些什么,那么,这个规则的变化不会对我们造成任何影响。这就是一个“简单就是美”例子--尽可能避开语言的细枝末节,别耍小聪明。)

2.函数内联

这个需要权衡。要之,默认将所有函数都实现为外联,有选择地将确实需要内联以提高效率的函数实现为内联。

当你将函数内联时,积极面是你避免了对f函数的调用的额外开销。

消极面是内联f暴露了f的实现,并使得用户的代码依赖于此实现,当f被改变时,所有的用户代码都必须被重编译。更严重的是,用户代码现在至少需要知道函数g()的原型,这有点恶心,因为用户根本没有直接调用函数g,原本可以根本不需要知道它的原型的(至少,从我们的例子上,是这样的)。于是,如果g()自己发生了变化,接受其它类型的其它参数时,用户的代码将变得也需要知道这些类型的申明。

内联和非内联都可以。必须在优缺点间进行权衡,取决于f现在是怎样被使用的以及使用的广泛程度,和将来可能变为怎样被使用的以及使用的广泛程度。

GotW给出的代码规范:

l 传参时,用传const的引用来代替传值

l 避免函数内联,除非profiler告诉你有这个必要(程序员在猜测效能瓶颈点方面是很不准的)

注1:这个改进是必要的,它避免了编译器未经允许地省略拷贝构造时带来问题,尤其当拷贝构造有副作用时。很多时候,代码需要计算对象的拷贝数目。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有