C++11的新特性

空指针

nullptr 空指针的字面值常量,它的类型是std::nullptr_t(定义位于cstddef)

自动类型推断

auto关键字,由auto定义的变量必须初始化。

统一初始化和初始化列表

C++11 introduced the concept of uniform initialization, which means that for any initialization, you can use one common syntax. This syntax uses braces, so the following is possible now:

int values[] { 1, 2, 3 };

std::vectorv { 2, 3, 5, 7, 11, 13, 17 };

std::vectorcities {"Berlin", "New York", "London", "Braunschweig", "Cairo", "Cologne"};

std::complexc{4.0,3.0}; // equivalent to c(4.0,3.0)

使用初始化列表初始化时,不提供初始值时默认值初始化(0或nullptr),其他初始化方式若为提供初始值则值是未定义的。

int i; // i has undefined value

int j{}; // j is initialized by 0

int* p; // p has undefined value

int* q{}; // q is initialized by nullptr

使用初始化列表初始化时,若提供的值会将会损失精度时,编译器报错。

int x1(5.3); // OK, but OUCH: x1 becomes 5

int x2 = 5.3; // OK, but OUCH: x2 becomes 5

int x3{5.0}; // ERROR: narrowing

int x4 = {5.3}; // ERROR: narrowing

char c1{7}; // OK: even though 7 is an int, this is not narrowing

char c2{99999}; // ERROR: narrowing (if 99999 doesn’t fit into a char)

std::vectorv1 { 1, 2, 4, 5 }; // OK

std::vectorv2 { 1, 2.3, 4, 5.6 }; // ERROR: narrowing doubles to ints

std::initializer_list<>使得函数支持传入多值(通过初始值列表)

void print (std::initializer_list vals){

           for (auto p=vals.begin(); p!=vals.end(); ++p) { 

                    std::cout << *p << "\n";

                    }

}

print ({12,3,5,7,11,13,17}); // pass a list of values to print()

基于范围的循环表达式

for ( decl : coll ) {

        statement

}

coll必须是支持迭代器的容器,或者是数组,或者是值列表类型

移动语义和右值引用

避免无意义的拷贝和暂存变量。

The programmer, however, has to specify that a move is possible unless a temporary is used.

std::move(),位于 。std::move(x)本身不会进行移动操作,只是将临时变量转换为一个右值引用(X &&x,使用双&声明,表明右值是可以修改的),表明此临时变量x将不会再使用了,可以将它的内容据为己有(不需要拷贝)。

移动之后不再使用原来的变量,原来的变量有效但是状态未定义。

void foo(X &x);//只接受左值

void foo(const X &x);//接受左值和右值

void foo(X &&x);//接受右值

原始字符串字面值、被编码的字符串字面值

Raw String Literals

此类型的字符串可包含特殊字符,语法R"delim(...)delim",delim是16个基本字符组成的分隔符除了反斜杠,空格,圆括号;

例如:R"(\\n)"对应的普通字符串是"\\\n"

常用来定义正则表达式。

Encoded String Literals

使用编码前缀,定义特殊编码的字符串常量:

u8:utf-8,const char

u:char16_t

U:char32_t

L:wchar_t

关键字noexcept

声明一个函数不能或不准备抛出异常。

void foo() noexcept;

若在foo函数内部没有处理发生的异常,程序会终止,调用std::terminate(),它默认调用std::abort();

关键字constexpr

使得表达式在编译期间判断是否是常量,或者修饰返回值返回一个常量。

constexpr int square (int x){

               return x * x;

}

float a[square(9)]; // OK since C++11: a has 81 elements

模板特性

Variadic Templates

可变模板参数个数,例如处理不同类型的参数

void print (){}

template

 void print (const T& firstArg, const Types&... args)

{

           std::cout << firstArg << std::endl; // print first argument

            print(args...); // call print() for remaining arguments

}

Alias Templates (Template Typedef)

template

using Vec = std::vector>; // standard vector using own allocator

Vec coll;//即std::vector> coll;

lambda表达式

基本语法:

[ capture list ] { function body } 或

[ capture list ]   ( paramters list )   mutable   throwSpec   -> retType { function body }

mutable、  throwSpec、  -> retType 可选

调用:直接调用、生成lambda变量间接调用

[ ] { std::cout << "hello lambda" << std::endl; } (); 或

auto func = [ ] (const std::string &s){ std::cout << "hello lambda"  <

func("good");

使用尾置返回:

未指明返回值类型时,若只有一个return语句,根据返回值自行推断;若有其他语句则返回void。

捕获规则:全局变量不用捕获即可使用

[ ]:不捕获任何变量

[=]:值捕获本作用域外变量

[&]:引用捕获作用域外变量

[x, &y]:显式值捕获x,引用捕获y

[=, &y]:值捕获除y的所有变量,y为引用捕获

[&, x]:引用捕获除x的所有变量,x为值捕获

值捕获变量在定义lambda时就已经确定,在内部不可更改其值,但使用mutable说明符可以使之改变。

lambda的类型

lambda的类型是匿名函数,每个不同的lambda的类型是不一样的。

#include

例如表达式

[ ] (int a, int b) -> int {  return a + b; }

的类型是std::function,用作返回值类型,可以返回一个lambda对象

std::functionreturnLambda () {

            return [] (int x, int y) { return x*y; };

}

auto f = returnLambda();

cout <

关键字decltype

编译器推断表达式的类型:用于声明返回值类型,元编程或传递lambda的类型

std::map coll;

decltype(coll)::value_type elem;

新的函数声明语法

template

auto add(T1 x, T2 y) -> decltype(x+y);//尾置返回,确定返回类型必须预先知道x,y的类型,但返回类型推断放在函数名前面无效(x,y类型此时未知)

作用域枚举(强枚举,枚举类)

enum class Salutation : char { mr, ms, co, none };

1,不可隐式的转换到int或从int转换

2,使用作用域运算符引用Salutation::mr;

3,可以显式定义类型(:char),否则默认是:int

4,可前向声明枚举类型

新的基本数据类型

char16_t, char32_t, long long, unsigned long long ,std::nullptr_t

其他新特性

Nontype Template Parameters

bitset<32> flags32; // bitset with 32 bits

bitset<50> flags50; // bitset with 50 bits

Default Template Parameters

template>

class MyClass;

MyClass x1;//即MyClass>

Keyword typename

用来说明其修饰的东西是类型

Member Templates

类的成员函数可以为模板

Nested Class Templates

嵌套类也可以为类模板

显式初始化基本数据类型

使用不带参数的显式构造初始化基本数据类型时,为0初始化(所有值都为0)

int i1; // undefined value

int i2 = int(); // initialized with zero

int i3{}; // initialized with zero (since C++11)

main函数的定义

1,

int main{}

2,

int main (int argc, char* argv[]){}

不一定要return 语句,隐式返回0,表示成功执行;返回非0则表示出错;

不使用return来结束程序可使用exit(), quick_exit(), terminate();

你可能感兴趣的:(C++11的新特性)