c++新特性之语法优化

模板表达式中的空格

1
2
vector<list<int> > //old 
vector<list<int>> //Ok since C++11

nullptr and std::nullptr_t

为了区分指针和整形增加了nullptr
使用nullptr 去代替0或者NULL

1
2
//<cstddef>
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); //int
f(12345);//int
f(nullptr);//void*
nullptr_t t;
if(t == nullptr) //true
{
std::cout<<"t == nullptr"<<std::endl;
}
f2(t); //nullptr_t
return 0;
}

auto

类型推倒 (一般使用在类型复杂,太长(迭代器),无法写的类型如lambda)

1
2
3
4
5
6
auto i = 42; //i 为int
auto l = [](int x)->bool{ //l为 匿名函数
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);

Uniform Initialization(统一初始化)

含义:任何初始化动作都可以用共同的一种语法来初始化

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的构造函数。