模板表达式中的空格
1 2
| vector<list<int> > vector<list<int>>
|
nullptr and std::nullptr_t
为了区分指针和整形增加了nullptr
使用nullptr 去代替0或者NULL
1 2
| typedef decltype(nullptr) nullptr_t
|
类型std::nullptr_t 可以定义类型
具体使用看下面测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| #include<cstddef> #include<iostream> void f(int) { std::cout<<"int"<<std::endl; } void f(void *) { std::cout<<"void*"<<std::endl; } void f2(void *) { std::cout << "void*" << std::endl; } void f2(nullptr_t) { std::cout<<"nullptr_t"<<std::endl; } int main() { f(0); f(12345); f(nullptr); nullptr_t t; if(t == nullptr) { std::cout<<"t == nullptr"<<std::endl; } f2(t); return 0; }
|
auto
类型推倒 (一般使用在类型复杂,太长(迭代器),无法写的类型如lambda)
1 2 3 4 5 6
| auto i = 42; auto l = [](int x)->bool{ return false; } vector<string> v; auto v = v.begin();
|
作为函数返回值 decltype可以提取表达式的类型
1 2 3 4 5 6
| auto i =42; auto l = [](int x) -> decltype(x) { std::cout<<x<<std::endl; return x; }; auto b = l(33);
|
含义:任何初始化动作都可以用共同的一种语法来初始化
1 2 3
| int values[] {1,2,3}; std::vector<std::string> cities {"beijing","shanghaii","xian"}; std::complex<double> c{4.0,3.0};
|
编译器看到{t1,t2…tn}时便做出一个initializer_list,它关联一个array<T,n>。调用函数时(如ctor)这个array内的 元素可以被编译器分解并传给函数。但是如果函数参数是initializer_list时(容器都会有一个参数为它的构造函数)如上面的vector初始化,调用者无法知道参数的个数此时会把它们(array<T,n>)自动转换为一个initializer传进去。
1
| std::vector<std::string> cities {"beijing","shanghaii","xian"};
|
上面的代码会形成一个 initializer_list,背后有一个 array<string,6>,调用vector ctors时编译器找到了一个接受initializer_list参数的构造函数。
1
| std::complex<double> c{4.0,3.0};
|
上面的代码生成一个initializer_list,背后有一个array<double,2>。调用complex的构造函数时,这个array内的两个元素被分解传给构造函数。complex没有可以接受参数为 initializer_list的构造函数。