C++Primer第五版学习(函数部分 五)特殊用途语言特性

特殊用途语言特性这一部分,主要是介绍三种函数相关的语言特性,分别是:默认实参、内联函数和constexpr函数。这部分内容相对简单。

1. 默认实参

某些函数有这样一种形参,在函数的很多次调用中它们都被赋予一个相同的值,此时,我们把这个反复出现的值称为函数的默认实参(default argument)。调用含有默认实参的函数时,可以包含该实参,也可以省略该实参。

比如,下面的代码:

typedef string::size_type sz; 
string screen (sz ht = 24, Sz wid = 80, char backgrnd = ' ');

这里需要注意的有:

我们可以为一个或多个形参定义默认值,不过需要注意的是,一旦某个形参被赋予了默认值,它后面的所有形参都必须有默认值。

函数调用时实参按其位置解析,默认实参负责填补函数调用缺少的尾部实参(靠右侧位置)。例如,要想覆盖backgrnd的默认值,必须为ht和wid提供实参:

以下的调用方式就是错误的:

window = screen (, , '?');//错误:只能省略尾部的实参

因此,当我们设计含有默认实参的函数时,其中一项任务是合理设置形参的顺序,尽量让不怎么使用默认值的形参出现在前面,而让那些经常使用默认值的形参出现在后面。

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

//表示高度和宽度的形参没有默认值
string screen (Sz, Sz, char =' ');

我们不能修改一个已经存在的默认值:

string screen (Sz, Sz, char = '*');//错误:重复声明

但是可以按照如下形式添加默认实参:

string screen (Sz = 24, Sz = 80, char);// 正确:添加默认实参

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

2.内联函数****和constexpr函数

规模较小的操作定义成函数有很多好处,主要包括:

  1. 阅读和理解shorterString函数的调用要比读懂等价的条件表达式容易得多。

  2. 使用函数可以确保行为的统一,每次相关操作都能保证按照同样的方式进行。如果我们需要修改计算过程,显然修改函数要比先找到等价表达式所有出现的地方再逐一修改更容易。

  3. ·函数可以被其他应用重复利用,省去了程序员重新编写的代价.

例如,如下代码:

//挑出两个string对象中较短的那个,返回其引用
const string &shorterstring (const string &sl, const string &s2)
{
  return sl.size () <= s2.size () ? s1 : s2;
}

内联函数可避免函数调用的开销将函数指定为内联函数(inline),通常就是将它在每个调用点上“内联地”展开。假设我们把shorterString函数定义成内联函数,则如下调用:

cout << shorterString (Sl, s2) << endl;

将在编译过程中展开成类似于下面的形式

cout << (sl.size() < s2.size () ? sl : s2) << endl;

从而消除了shorterString函数的运行时开销。

在shorterString函数的返回类型前面加上关键字inline,这样就可以将它声明成内联函数了:

//内联版本:寻找两个string对象中较短的那个
inline const string &shorterstring (const string &sl, const string &s2)
{
    return sl.size () <= s2.size () ? sl : s2;
}

一般来说,内联机制用于优化规模较小、流程直接、频繁调用的函数。


constexpr 函数

constexpr函数(constexpr function)是指能用于常量表达式的函数。

定义constexpr函数的方法与其他函数类似,不过要遵循几项约定:

函数的返回类型及所有形参的类型都得是字面值类型,而且函数体中必须有且只有一条return语句:

constexpr int new_sz () f return 42; )constexpr 
int foo = new_sz(); // 正确: foo是一个常量表达式

把new_sz定义成无参数的constexpr函数。因为编译器能在程序编译时验证new_Sz函数返回的是常量表达式,所以可以用new sz函数初始化constexpr类型的变量foo。执行该初始化任务时,,编译器把对constexpr函数的调用替换成其结果值。为了能在编译过程中随时展开,constexpr函数被隐式地指定为内联函数。

猜你喜欢

转载自blog.csdn.net/xu_fu_yong/article/details/123214869