本文转自:http://zhangjunxin520.blog.163.com/blog/static/3050370320116210101891/
本文的主要内容来源:
http://www.softwarequalityconnection.com/2011/06/nullptr
)async()
功能,及多线程库。Lambda表达式允许你在本地定义函数,即在调用的地方定义,
从而消除函数对象产生的许多安全风险,Lambda表达式的格式如下:
[capture](parameters)->return-type {body}[]里是函数调用的参数列表,表示一个Lambda表达式的开始,
让我们来看一个Lambda例子:
假 设你想计算某个字符串包含多少个大写字母,使用for_each()遍历一个char数组,
下面的Lambda表达式确定每个字母是否是大写字母,每当它 发现一个大写字母,
Lambda表达式给Uppercase加1,Uppercase是定义在Lambda表达式外的一个变量:
int main()以上例子就好像你在一个函数调用内部定义了一个新的函数。[&Uppercase]中的“&”记号
意味着Lambda主体获得一个 Uppercase的引用,以便它能修改,如果没有这个特殊记号,
Uppercase将通过值传递,C++11 Lambda表达式也包括成员函数构造器。
2. 自动类型推导和声明类型(decltype)
在C++03中,在声明对象时,你必须指定对象的类型,然而,在许多情况下,
对象声明时都有初始化,C++11利用了这个优势,允许你声明对象时不指定类型:
auto x=0; // x has type int because 0 is int考虑下面迭代器的声明:
void fucn(const vector<int> &vi)关 键字auto不是什么新生事物,我们早已认识,它实际上可以追溯到前ANSI C时代,
但是,C++11改变了它的含义,auto不再指定自动存储类型对象,相反,它声明的对象
类型是根据初始化代码推断而来的,C++11删除了 auto关键字的旧有含义以避免混淆。
注意了:auto已经不再是当年的auto了!
C++11提供了一个类似的机制捕捉对象或表达式的类型,新的操作符decltype需要一个
表达式,并返回它的类 型。
const vector<int> vi; typedef decltype (vi.begin()) CIT; CIT another_const_iterator;
3. 统一初始化语法(uniform initialization syntax)C++至少有4个不同的初始化符号,有些存在重叠,
括号初始化语法如下:
std::string s("hello");在某些情况下,你也可以使用“=”符号进行初始化:
std::string s="hello";对于POD聚合,你还可以使用大括号:
int arr[4]={0,1,2,3};最后,构造函数使用成员进行初始化:
struct S {显然,这么多种初始化方法会引起混乱,对新手来说就更痛苦了,更糟糕的是,
在C++03中,你不能初始化POD数组成员,POD数组使用new[]分配,
C++11使用统一的大括号符号清理了这一混乱局面。
class C {对于容器,你可以和一长串的push_back()调用说再见了,在C++11中,
你可以直观地初始化容器:
// C++11 container initializer类似地,C++11支持成员在类内初始化:
class C {
int a=7; //C++11 only 这和Java一样
public:
C();
};
4. 代理构造(delegating constructors)
在C++11中,构造函数可以调用类中的其它构造函数:
class M //C++11 delegating constructors构造函数#2,代理构造函数,调用目标构造函数#1。
5. deleted 和defaulted函数声明(deleted and defaulted function declarations)
一个结构体中的函数:
struct A {对于被称为defaulted的函数,“=default;”部分告诉编译器为函数生成默认实现。
Defaulted函数有两个好处:比手工实现更高效,让程序员摆脱了手工定义这些函数的麻烦事。
与defaulted函数相反的是deleted函数:
int func()=delete;Deleted函数对防止对象复制很有用,回想一下C++自动为类声明一个拷贝构造函数和一个赋值操作符,
要禁用拷贝,声明这两个特殊的成员函数为=delete即可:
struct NoCopy {
6. 空指针(nullptr
)
终于,C++有了一个指定空指针常量的关键字,nullptr取代了有错误倾向的NULL宏和0,
这两个空指针替代品已经使用很多年了,nullptr是一个强类型:
void f(int); //#1nullptr适用于所有指针类别,包括函数指针和成员指针:
const char *pc=str.c_str(); //data pointers7. 右值引用(rvalue references)
C++03中的引用类型只能绑定左值,C++11引入了一种新的引用类型,叫做右值引用,这样的代价很高,复制字符串必须分配原始内存,将字符从源拷贝到目标。
相反,移动字符串仅仅是交换两个数据成员,不用分配内存,拷贝char数组和删除内存:
void moveswapstr(string& empty, string & filled)
{
//pseudo code, but you get the idea
size_t sz=empty.size();
const char *p= empty.data();
//move filled's resources to empty
empty.setsize(filled.size());
empty.setdata(filled.data());
//filled becomes empty
filled.setsize(sz);
filled.setdata(p);
}
如果你实现的类支持移动,你可以像以下那样声明一个移动构造函数和一个移动赋值操作符:
class MovableC++11标准库广泛的使用了移动语义,许多算法和容器都为移动做了优化。