C++ 11
auto
- 使用 auto 必须初始化;
- auto 根据初始化的值来推导数据类型;
- 当类型不为引用时,auto 的推导结果将不保留表达式的 const 属性;
- 当类型为引用时,auto 的推导结果将保留表达式的 const 属性。
限制
- 不能再函数参数中使用
- 不能作用于类的非静态成员变量(没有 static 关键字的变量)
- 不能定义数组;
- 不能用于模板参数
应用
- 迭代器
- 泛型编程
decltype
“declare type”的缩写。
和 auto 相似,用于自动的类型推导。
decltype(exp) varname = value;
根据 exp 推出类型,而不是 value 。
不要求变量初始化。
推导
exp是变量,则类型为变量exp是函数,则类型为函数返回类型exp是左值,则类型为exp的引用
应用
- 非静态成员
auto 和 decltype 区别
- auto 可能不保留 const 等限定符,decltype 则会保留。
1 | //非指针非引用类型 |
对引用的处理
- auto 抛弃引用类型,decltype 保留引用类型
1 |
|
模板
返回值类型后置
模板实例化中>> 符号的改进
在 C++ 98/03 中,>>符号通常被编译器解释为右移操作符,通常会提示在两个尖括号中间添加空格。
现在 C++ 11 对模板的 >> 符号进行了单独处理,不再出问题。
当然在需要右移操作符时,最好用括号将表达式括起来。
使用 using 代替 typedef 定义别名
1 | template <typename Val> |
改成:
1 | template <typename Val> |
- typedef 具有语法一致性,但遇到复杂的会降低可读性
- using 直接在后面用赋值的方式,更清晰
1 | /* C++98/03 */ |
使用 using 可以轻松地创建一个新的模板别名,而不需要像 C++98/03 那样使用烦琐的外敷模板。
支持函数模板的默认模板参数
在函数模板和类模板中使用可变参数
可变参数模板
tuple 元组详解
列表初始化
lambda 匿名函数
非受限联合体(union)
1. C++11 允许非 POD 类型
POD 类型一般具有以下几种特征(包括 class、union 和 struct 等):
- 没有用户自定义的构造函数、析构函数、拷贝构造函数和移动构造函数。
- 不能包含虚函数和虚基类。
- 非静态成员必须声明为 public。
- 类中的第一个非静态成员的类型与其基类不同,例如:
class B1{};
class B2 : B1 {B1 b;};
class B2 的第一个非静态成员 b 是基类类型,所以它不是 POD 类型。
- 在类或者结构体继承时,满足以下两种情况之一:
- 派生类中有非静态成员,且只有一个仅包含静态成员的基类;
- 基类有非静态成员,而派生类没有非静态成员。
- 所有非静态数据成员均和其基类也符合上述规则(递归定义),也就是说 POD 类型不能包含非 POD 类型的数据。
- 此外,所有兼容 C 语言的数据类型都是 POD 类型(struct、union 等不能违背上述规则)。
2. C++11 允许联合体有静态成员
3. 注意
C++11 规定,如果非受限联合体内有一个非 POD 的成员,而该成员拥有自定义的构造函数,那么这个非受限联合体的默认构造函数将被编译器删除;其他的特殊成员函数,例如默认拷贝构造函数、拷贝赋值操作符以及析构函数等,也将被删除。
这条规则可能导致对象构造失败。
例子:
1 |
|
解决问题要用到 placement new ,如下:
1 |
|
placement new
语法:new(address) ClassConstruct(…)
- address 是内存地址。
- ClassConstruct 表调用类的构造函数,如没有可省略括号
placement new 利用已经申请好的内存来生成对象,它不再为对象分配新的内存,而是将对象数据放在 address 指定的内存中。在本例中,placement new 使用的是 s 的内存空间。
非受限联合体的匿名声明和 “枚举式类”
for 循环(基于范围的循环)详解
C++ 11 :
1 | for (declaration : expression){ |
例子:
1 |
|
注意事项
- 不管是遍历什么,即使是遍历容器,也不是遍历指向各个元素的迭代器,而是容器中的各个元素。
- 用范围的方式还可以遍历字符串
- 不支持遍历指针形式返回的数组(需要范围明确)
- 遍历 string 或容器时,遍历过程中函数只执行一次,如下
1 |
|
- 使用基于范围的循环时,不修改容器中不允许被修改的部分
- 基于范围的循环,其底层也是借助容器迭代器实现
1 |
|

