c++11常见新特性总结
为什么要总结,主要是面试可能问,要回答的有体系,二是项目需要也得了解了解
参照原文链接
1. nullptr
nullptr 主要用来替代 NULL,考虑以下场景
c++11之前
1. void foo(char *);
2. void foo(int);
char *c = NULL;
NULL可能被定义为(void*0) 或者 0 ;如果NULL被定义为0,调用 foo(NULL)
就会选择 2 ,C++ 中重载特性会发生混乱,有点不太好理解了。
2. 类型推导
新增了auto 和 decltype
- 对于用auto修饰的变量一定要初始化
- auto不可以作为函数的参数和返回值
- 用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&
有了auto为什么还要有decltype?肯定有点啥区别
decltype 关键字是为了解决 auto 关键字只能对变量进行类型推导的缺陷而出现的,它可以使编译器自动分析表达式的类型并得到它的类型,最关键是它不会去计算表达式的值
auto x = 1;
auto y = 2;
decltype(x+y) z;
3. 区间迭代 - 基于范围的 for 循环
string s;
for(auto c : s)
cout << c;
确实很方便
4. 初始化列表
为了统一初始化方式,并且让初始化行为具有确定的效果
C++11 中可以使用列表初始化方法对堆中分配的内存的数组进行初始化,而在 C++98/03 中是不能这样做
// 列表初始化(c++98编译失败 c++11编译通过)
Foo a3 = { 123 };
// 列表初始化(c++98编译通过 c++11编译通过)
Foo a4 { 123 };
int* a = new int { 123 };
5. 模板增强
5.1 外部模板
传统c++,模板只有在使用的时候才会实例化;只要在每个文件中编译的代码遇到被完整定义的模板都会实例化,产生重复实例化
外部模板能 显式地告诉编译器何时进行模板实例化
// 强行实例化
template class std::vector<bool>;
// 不在该编译文件中实例化模板
extern template class std::vector<double>;
5.2 默认模板参数
template
使用模板时不用指定模板参数类型
6. Lambda表达式
[capture list] (parameter list) option -> return type { body}
capture list: 捕获列表
- [] 不捕获变量
- [&]按引用捕获外部作用域中的所有变量
- [=]按值捕获外部作用域中的所有变量
- [a]按值捕获a变量
- [this]捕获当前类中this指针,如果已经使用 & 或 =,默认添加
- Parameter list 为形参列表。(选填)
- option 是函数选项;
可以填mutable,exception,attribute。(选填)- mutable说明lambda表达式体内的代码可以修改被捕获的变量,并且可以访问被捕获的对象的non-const方法。
- exception说明lambda表达式是否抛出异常以及何种异常。
- attribute用来声明属性。
- return type 表示该 lambda 的返回类型。(选填)
- Function body 是函数体
7.新增容器
7.1 array
- array保存在栈内存,相比于堆内存vector,能更灵活的访问元素
- array 会在编译时创建一个固定大小的数组
int len = 4; std::array<int, len> arr = {1,2,3,4}; // 非法, 数组大小参数必须是常量表达式1234
- array 不能够被隐式的转换成指针
// C 风格接口传参 // foo(arr, arr.size()); // 非法, 无法隐式转换 foo(&arr[0], arr.size()); foo(arr.data(), arr.size());
7.2 无序容器
C++11 引入了两组无序容器: std::unordered_set/std::unordered_multiset
和std::unordered_map/std::unordered_multimap。
无序容器中的元素是不进行排序的,内部通过 Hash 表实现,插入和搜索元素的平均复杂度为 O(constant)。
7.3 元组
元组的使用有三个核心的函数:
- std::make_tuple: 构造元组
- std::get: 获得元组某个位置的值
- std::tie: 元组拆包