<C++基础学习二十一>特殊用途语言特性

摘要: 本篇博客仅作为笔记,如有侵权,请联系,立即删除(网上找博客学习,然后手记笔记,因纸质笔记不便保存,所以保存到网络笔记)。

  一、默认实参

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

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

  其中我们为每个形参都提供了默认实参,默认实参作为形参的初始值出现在形参列表中。

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

  二、使用默认形参调用函数

  如果我们想使用默认形参,只要在调用函数的时候忽略该实参就可以了。

  函数调用时实参按其位置解析,默认实参负责填补函数调用缺少的尾部实参(靠右侧位置)。

  所以在设计默认实参的函数时,应该合理设置形参的顺序,尽量让不怎么使用默认的形参出现在前面,而让那些经常使用默认值的形参出现在后面。

  三、默认实参声明

  对于一个函数声明,通常的习惯就是将它放在头文件中,并且一个函数只声明一次,但是多次声明同一个函数也是合法的。

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

//表示高度和宽度的形参没有默认值
string screen(sz,sz,char = ' ');
//错误,重复声明,不能修改一个已经存在的默认值
string screen(sz,sz,char = '*');
//正确,添加默认实参
string screen(sz = 24,sz = 80,char);

  通常应该在函数声明中指定默认实参,并将声明放在合适的头文件中。

  四、默认实参初始值

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

//wd def ht的声明必须在函数外
sz wd = 80;
char def = ' ';
sz ht();
string screen(sz = ht(),sz = wd,char = def);

//调用screen(ht(),80,' ');
string window = screen();

  用作默认实参的名字在函数所在作用域内解析,而这些名字的求值过程发生在函数调用时

void f2(){
    //改变了默认实参值
    def = '*';
    //隐藏了外部定义的wd,但是没有改变实参值
    sz wd = 100;
    //调用screen(ht(),80,'*');
    window screen();        
}

  f2内部改变了def值,所以对screen的调用会传递这个更新过的值,虽然我们函数还声明了一个局部变量用于隐藏外部的wd,但是该局部变量与传递给screen的默认实参没有任何关系。

  五、内联函数

  把函数指定为内联函数,通常就是将它在每个调用点上“内联地”展开。避免函数调用的开销

inline const string& shorterString(const string &s1,const string &s2){
    return s1.size() <= s2.size() ? s1 : s2;
}

cout << shorterString(s1,s2) << endl;
//该调用在编译过程中展开成类似于下面的形式:
cout << (s1.size() <= s2.szie() ? s1 : s2) << endl;

  内联说明只是向编译器发出的一个请求,编译器可以忽略这个请求。

  六、constexpr函数

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

  需要遵循以下几项约定:

  1、函数的返回类型及所有形参的类型都是字面值类型

  2、函数体中必须有且只有一条return语句

  3、函数体可以包含其他的语句,但是这些语句不能再运行期起作用

  4、函数不可以返回常量,但是在调用的时候实参必须传入常量表达式

constexpr int new_sz() {return 42;}
constexpr int foo = new_sz();

  new_sz()无参数,返回值是常量表达式。

  new_sz()可以初始化constexpr类型的变量foo

  在编译时constexpr函数被隐式指定为内联函数。

  constexpr返回值并非一个常量:

//如果arg是常量表达式,则scale(arg)也是常量表达式
constexpr size_t scale(size_t cnt) {return new_sz() * cnt;}
//正确,scale(2)是一个常量表达式
int arr[scale(2)];
//错误,scale(i)不是一个常量表达式
int i = 2;
int a2[scale(i)];
posted @ 2019-01-13 21:34  daisy_ai  阅读(132)  评论(0编辑  收藏  举报