###C++ Primer第5版 学习笔记
####第六章
- 函数实参求值顺序取决于编译器
- 列表形参为空,相当于 void
- 名字 -> 作用域,对象 -> 生命周期
- 只存在于块执行期间的对象称为自动对象,形参是自动对象
- 局部静态变量在程序执行路径第一次经过对象定义语句时初始化,直到程序终止才被销毁,内置类型的.如果没有显式初始值,局部静态变量初始化为 0
- .obj(Windows) .o(UNIX)含义是文件包含对象代码(object code)
- 实参初始化形参时会忽略顶层 const
- 尽量使用常量引用,不能把 const 对象,字面值,需要类型转换的对象传递给普通的引用实参
```
void print(const int*);
void print(const int[]);
void print(const int[10]);//10没有意义
```
上面三个等价,编译器只会检测实参是否是(或者能转换为) const int *
-
C++ 允许将变量定义成数组的引用,形参也可以是数组的引用
void print(int (&arr)[10]) { for (auto elem : arr) { cout << elem << endl; } }
不过数组的大小是构成数组类型的一部分,只能将此函数作用于大小为 10 的数组
11. 对同类型可变形参,可以传递 initializer_list 类型,列表中的元素是 const
```
void error_msg(initializer_list<string> li) {
for (auto beg = li.begin(); beg != li.end(); ++beg) {
cout << *beg << " ";
}
for(auto &i : li) {//因为有 begin 和 end 成员,所以可以使用范围 for 循环
cout << i << " ";
}
}
error_msg({"function a", "okay"});//调用
```
12. 对不同类型的可变形参,可使用可变参数模板
13. 函数如果返回指针,引用,类的对象,就能直接使用函数调用的结果访问结果对象的成员.调用一个返回引用的函数返回左值,其他则返回右值
14. C++11 可以返回花括号包围的值得列表
```
vector <string> process() {
return {"function a", "okay"};
}
```
如果函数返回类型为内置类型,花括号中只能有一个值,且如果有类型转换,占用空间不能减小。返回类类型,则由类本身定义初始值如何使用(相当于值初始化的花括号形式)
15. 尾置返回类型可用于任何函数,对返回类型比较复杂的函数最有效
```
auto func(int i) -> int(*)[10]//返回值类型为指向含有10个int的数组的指针
```
如果知道返回指针指向的数组,也可使用 decltype
```
int odd[] = {1,3,5,7,9};
int even[] = {0,2,4,6,8};
decltype(odd) *arrPtr(int i) {
return (1 % 2) ? &odd : &even;
}
```
16. 形参顶层 const 没有区别,底层 const 与非常量形参可重载,对非常量对象或指向非常量对象的指针,优先使用非常量版本
17. 在不同的作用域中无法重载函数名,名字查找发生在类型检查之前
18. 通常应在函数声明中指定默认形参,并放在头文件中,多次声明同一函数合法
19. 用作默认形参的名字在函数声明所在的作用域进行解析,但求值发生在函数调用时
20. constexpr 函数能用于常量表达式,返回值类型,所有形参的类型都得是字面值类型,函数体中必须有且只有一条 return 语句,constexpr 函数被隐式指定为内联函数
21. 内联函数和 constexpr 函数可以多次定义,但必须完全一致,因此通常定义在头文件中
22. assert(expr),对 expr 求值,为假则输出信息并终止程序,assert 是预处理宏,在定义了 NDENUG 时 assert 才有效
23. 重载函数进行函数匹配时,所有的算数类型转换级别都一样
24. 定义返回函数指针的函数时
```
using F = int(int*, int);
using FP = int(*)(int *, int);
FP f1(int);//对,返回类型为指针
F f1(int);//错,返回类型不能是函数
F *f1(int);//对,显式指定返回类型为指针
auto f(int) -> int (*) (int *, int)//返回值为函数指针
int f(int);
decltype (f) *getfun(int i);//decltype返回函数类型,而不是指针类型
```