1. 头文件写法变化
c++ 标准库头文件不带 .h,#include<vector>
c 新式也不带.h, #include<cstdio>
2. Spaces in Template Expressions
新特性去掉了"< > >"
之间的空格,—> "< >>"
3. nullptr、0、NULL
// nullptr的意思告诉编译器传递的是 空指针
void f(int) { cout << "f(int)\n"; }
void f(void*) { cout << "f(void*)\n"; }
int main()
{
f(0); // f(int)
f(nullptr); // f(void*)
return 0;
}
4. auto
自动推断变量类型
编译器本来就知道变量的类型. 完成自动推断当然可以.
auto it; // error 这是在调戏编译器,鬼知道你要什么类型
一般用于类型名很长,很复杂的情况.
vector<string>::iterator it = v.begin();
|
V
auto it = v.begin();
5. Uniform Initialization(一致性初始化)
“{ }”
背后就是形成了initializer_list<T>
.
背后是这个类initializer_list<T>
在发挥作用
6. range-based for
statement
有的容器不能通过迭代器改变元素, 关联式容器( set
map
multiset
multimap hashset hashmap)
都不可以.
一个容器的迭代器实现,一个通过全局函数begin()
, end()
.
7. noexcept
满足条件下保证函数不丢异常, 默认条件为真(不丢异常)。
在vector
和deque
调用构造函数时,必须保证构造函数不丢异常。在memory relocation
时,只在vector
和deque
中存在, grow
move
&&
跟搬移有关。
8. override
在重写虚函数时,函数签名肯定要相同,否则不叫override。
为防止出现程序员 想重写但是失误导致了签名不同,于是2.0提供了新的关键字override
,告诉编译器我想重写,你帮我检查签名有没有问题。
9. final
- 针对类: 父类的终极设计者,不要继承这个类,加上
final
。 - 针对虚函数: 继承了一个类,不能重写那个被
final
的虚函数。
10. decltype
通过decltype
可以获取对象的类型。
vector<int> v; // 在很远的地方定义了一个v
// 以下两句一个意思
decltype(v)::value_type a; // 先获取v的类型名,再使用它的value_type,这里就是int了
int a;
map<string, int> map1;
// `key_type`就表示map中`key`的类型。以下三句是一个意思:
map<string, int>::key_type m;
string m;
decltype(map1)::key_type m;
decltype对应有三种用法
10.1 用于函数返回值
函数返回类型的指定方式 的写法
template<typename T1, typename T2>
auto add(T1x, T2 y) ->decltype(x+y);
10.2 在类中使用
取个别名,在编译器编译到这一句时,并不知道obj的类型,所以前面要加typename
。
当然要说明obj对象肯定要包含有iterator
否则用的时候可能会出问题。
typedef typename decltype(obj)::iterator iType;
10.3 用于lambda
后面一堆函数要用cmp这个对象来表现,一般很少也很难写出lambda
表达式的类型。可以用decltype
来获取它的类型。