前言
这里简单记录下
《深入应用c++11 祁宇 著》
的学习笔记
c++11学习笔记 《深入应用c++11 祁宇 著》
作者博客
GitHub地址
第一篇 改进我们的程序
第1章 使用C++11让程序更简洁、更现代
1-1 类型推导auto
decltype
auto
的推导规则:当不声明为指针或者引用时,
auto
的推导结果和初始化表达式抛弃引用和cv
限定符后的类型一致;
当声明为指针或者引用时,auto
的推导结果将保持初始化表达式的cv
限定符属性;1
2
3
4
5
6
7
8
9//存储说明符
auto //...
register //修饰符暗示编译程序相应的变量将被频繁地使用,不能& https://blog.csdn.net/21aspnet/article/details/257511
static //...
extern //告诉编译器是外部变量
mutable //修饰的变量,将永远处于可变的状态,突破const
//cv限定符
const //...
volatile //防止编译器优化auto
的限制- 不能用于函数参数
- 不能用于非静态
const
成员变量 - 无法定义数组
- 无法推导出模板参数
decltype
的推导规则1
decltype(exp)
- exp是标识符、类访问表达式,
decltype(exp)
和exp的类型一致 - exp是函数调用,
decltype(exp)
和和exp的返回值类型一致 - 若exp是一个左值,则
decltype(exp)
是exp类型的左值引用,否则和exp类型一致
规则2备注说明 对于纯右值而言,只有
class
类型会保留cv
限定符,其他一般忽略掉cv
限定,如下:??? vs2019测试结果和该说法不符,
class
类型也会忽略cv
限定1
2
3
4
5
6
7class Foo {}
const int func_cint(void); //纯右值
const Foo func_cfoo(void); //纯右值
decltype(func_cint()) a = 0; //a-->int
decltype(func_cfoo()) f = Foo(); //f-->const Foo ??? vs2019 -->Foo规则3备注说明 带括号的表达式和加法运算表达式
foo.x 是左值,可知(foo.x)也是左值,因此decltype的结果是右值引用
foo是const,foo.x是一个const int类型左值,所以decltype的结果是const int&
m + n 返回一个右值;m += n 返回一个左值1
2
3
4
5
6
7
8
9struct Foo { int x; };
const Foo foo = Foo();
decltype(foo.x) a = 0; //a-->int
decltype((foo.x)) b = a; //b-->const int&
int m = 0, n = 0;
decltype(m + n) c = 0; //c-->int
decltype(m += n) d = a; //d-->const int&- exp是标识符、类访问表达式,
返回类型后置语法–
auto
和decltype
的结合使用1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16template<typename T, typename U>
auto add(T t, U u) -> decltype(t + u) {
return (t + u);
}
auto x = add(1, 2.0);
//////////////////////////////
int& foo(int& i) { return i; };
float foo(float& f) { return f; };
template<typename T>
auto func(T& val) ->decltype(foo(val)) {
return foo(val);
}
int i = 0;
auto x = func(i);auto
和decltype
的区别auto
修饰的的变量必须初始化;decltype
可以推导未初始化的变量decltype
可以获得表达式的类型,并且可以推导出定义本身的类型,不会像auto
可能丢弃引用和cv
限定符
1-2 模板的细节改进
c++11改进了编译器的解析规则,尽可能地将多个右尖括号(>)解析成模板参数结束符
- 在
c++98/03
的泛型编程中,连续两个右尖括号(>>)会被编译器解释成右移操作符,而不是模板参数表的结束;Foo<A<int>>
这种写法不被支持,要写成Foo<A<int> >
注意两个右尖括号之间的空格;
1 | template<typename Val> |
1 | template<typename T> |
- 当默认模板参数和模板参数自动推导同时使用时,若函数模板无法自动推导出参数类型,则编译器将使用自动推导出的参数类型;否则将使用自动推导类型
identity
外敷模板 禁用了形参val的类型自动推导 ,由于func
制定了模板参数T默认为int
,因此func(123)
的val参数为int
类型;在func(123, 123.456)
的第二参数为double
类型,模板参数T将优先自动推导为double
,因此func(123, 123.456)
的val参数为double
类型
ps. 默认模板参数不是模板参数自动推导的“建议”,模板参数自动推导总是根据实参推导来的,当自动推导类型生效时,默认模板参数类型会被忽略
1-3 列表初始化
1-4 基于范围的for
循环
第2章 使用C++11改进程序性能
[TODO]
第3章 使用C++11消除重复,提高代码质量
[TODO]
第4章 使用C++11解决内存泄露的问题
[TODO]
第5章 使用C++11让多线程开发变得简单
[TODO]
第6章 使用C++11中便利的工具
[TODO]
第7章 使用C++11的其他特征
[TODO]
第二篇 C++11工程级应用
第8章 使用C++11改进我们的模式
[TODO]
查看源码
第9章 使用C++11开发一个半同步半异步线程池
第10章 使用C++11开发一个轻量级的AOP库
第11章 使用C++11开发一个轻量级的IoC容器
第12章 使用C++11开发一个对象的消息总线库
第13章 使用C++11封装sqlite库
第14章 使用C++11开发一个linq to objects库
[TODO]
查看源码