新C++11语言特征
1. 在模版表达式中的空格已经不需要了
vector<list<int> > old_style_vecL; vector<list<int>> new_style_vecL; //OK since C++11
C++11让nullptr代替0或NULL来明确提出没有指向一个值,这并不与没有值等价,这个新特征能够使我们避免一些空指针被当作整型变量。eg:
void f(int); void f(void*); f(0); // 调用 f(int) f(NULL); //调用 f(int) f(nullptr); //调用 f(void *)
3. auto 自动类型推断
在C++11之前,类型推断主要用于容器类的迭代器类型名太长而做的推断,在C++11,自动推断更加普通,对基本类型、对象等都能做自动推断。需要注意的,做自动类型推断时,必需在声明时初始化。
auto i = 42 ; // int 类型 double f(); auto d = f(); // double 类型 //auto j; // ERROR 没有在声明时初始化 static auto vat = 0.12; // OK auto l = [](int i) -> int {cout << i << endl; return i;}; //Lambda表达式类型推断
在C++11之前,变量初始化通常以括号、大括号、赋值操作符提供,也就是说,特定类型的初始化方法并不一定相同,不具有通用性
在C++11,引入了通用的语法{},但使用通常有个限制:
不能丢失精度赋值,如不能从double 转变成为 int 型,需要显示转换。这个特征会避免产生一些不兼 容的代码。
int arr[] {1,2,3}; vector<int> v{1,2,3}; vector<string> strs{ "a", "b","c" }; std::complex<double> c{2.0,3.0}; int i ; // i有 未定义值 int j{}; //j = 0 int *p; // p有 未定义值 int *q{}; // q = nullptr int x1(5.3); // C++11之前初始化中的一种,x1 = 5; int x2 = 5.3; // x2 = 5; //int x3{5.3} // ERROR ,C++11通用初始化不能丢失精度 char c1{7}; //OK char c2{9999}; //ERROR
为了使用户定义的类型能够支持这种列表初始化,C++11引进了类模版std::initializer_list<>
class P { public: P(int,int); P(initializer_list<int>); //explicit P(initializer_list<int>); }; P p(77,5); // 调用P(int,int) P q{77,5}; // 调用 P(initializer_list<int>) P r{77,4,43}; // 调用 P(initializer_list<int>) P s = { 7, 5 }; // 调用 P(initializer_list<int>) //初始化列表也可以做为参数传递给函数 void print(initializer_list<int> vals) { for (const int& ele : vals) cout << ele << endl; }
在上面的例子中,为了使初始化列表不能够转换成对象,也就是说,禁用表达式 P s = {7,5}; 需要启用关键字 explicit 在构造函数之前。使用了explicit 之后,同时也应该知道,对于下面代码是错误的。
void fp(const P& ); fp({1,2,3}); // ERROR