(36) 默认实参、内联函数和constexpr函数

来源:互联网 发布:php小偷源码 编辑:程序博客网 时间:2024/06/05 16:37

默认实参

某些函数有这样一种形参,在函数的很多次调用中他们都被赋予一个相同的值,我们把这个反复出现的值称为函数的默认实参,调用含有默认实参的函数时,可以包含该实参,也可以省略该实参。
形式如下:
typedef string::size_type sz;string screen(sz ht =24,sz wid =80,char backgrnd =' ');
默认实参作为形参的初始值出现在形参列表中。我们可以为一个或多个形参定义初始值,不过一旦某个形参被赋予了默认值,它后面的所有形参都必须有默认值。

如果我们想使用默认实参,只要在调用函数的时候省略该实参就可以了,函数调用时实参按其位置解析,默认实参负责填补函数调用缺少的尾部实参。当设计含有默认实参的函数时,其中一项任务是合理设置形参顺序,尽量让不怎么使用默认值的形参出现在前面,而让那些经常使用默认值的形参出现在后面。  

在给定的作用域中一个形参只能被赋予一次默认实参。函数的后续声明只能为之前那些没有默认值的形参添加默认实参,而且该形参右侧的所有形参必须都有默认值。

局部变量不能作为默认实参。除此之外,只要表达式的类型能转换成形参所需的类型,该表达式就能作为默认实参。

内联函数

调用函数一般比求等价表达式的值要慢一些。在大多数机器上,一次函数调用其实包含一系列工作:调用前要先保存寄存器,并在返回时恢复,可能需要拷贝实参,程序转向新的位置继续执行。内联函数可以避免函数调用的开销,但是它结构简单,规模较小。

将函数指定为内联函数,通常是将它在每个调用点上“内联地”展开。假设我们把shorterString函数定义成内联函数,则如下调用:
cout<<shorterString(s1,s2)<<endl;
将在编译过程中展开类似于下面的形式
cout<<(s1.size()<s2.size()? s1:s2)<<endl;
从未消除了shorterString函数的运行时开销。
在shorterString函数的返回类型前面加上关键字inline,这样就可以将它声明称内联函数了:
inline const string & shorterString(const string &s1,const string &s2){return s1.size()<=s2.size()? s1:s2;}
一般来说,内联机制用于优化规模较小、流程直接、频繁调用的函数。很多编译器都不支持内联递归函数,而且一个75行的函数也不大可能在调用点内联地展开。内联说明只是向编译器发出的一个请求,编译器可以选择忽略这个请求。

constexpr函数

constexpr函数是指能用于常量表达式的函数。
定义constexpr函数的方法与其他函数类似,不过要遵循几项约定:函数的返回类型及所有形参的类型都得是字面值类型,而且函数
体中必须有且只有一条return语句:
constexpr int new_sz(){ return 42};

执行该初始化任务时,编译器把对constexpr函数的调用替换成其结果值。为了能在编译过程中随时展开,constexpr函数被隐式地指定为内联函数。

constexpr函数体内也可以包含其它语句,只要这些语句在运行时不执行任何操作就行,如:空语句,类型别名以及using声明。

注意:constexpr函数不一定返回常量表达式

内联函数和constexpr函数通常定义在头文件中。
0 0
原创粉丝点击