C++11标准库新加功能详解


C++11标准库新加功能详解

文章插图
 
一、Lambda表达式的引进
Lambda表达式的形式是这样的:
[capture](parameters)->return-type{body}
来看个计数某个字符序列中有几个大写字母的例子:
1. intmain()
2. {
3. chars[]="HelloWorld!";
4. intUppercase=0;//modifiedbythelambda
5. for_each(s,s+sizeof(s),[&Uppercase](charc){
6. if(isupper(c))
7. Uppercase++;
8. });
9. cout<<Uppercase<<"uppercaselettersin:"<<s<<endl;
10. }
其中[&Uppercase]中的 &的意义是 lambda函数体要获取一个 Uppercase引用,以便能够改变它的值,如果没有 &,那就 Uppercase将以传值的形式传递过去 。
二、自动类型推导和decltype
在 C++03中,声明对象的同时必须指明其类型,其实大多数情况下,声明对象的同时也会包括一个初始值,C++11在这种情况下就能够让你声明对象时不再指定类型了:
1. autox=0;//0是int类型,所以x也是int类型
2. autoc='a';//char
3. autod=0.5;//double
4. autonational_debt=14400000000000LL;//longlong
这个特性在对象的类型很大很长的时候很有用,如:
1. voidfunc(constvector<int>&vi)
2. {
3. vector<int>::const_iteratorci=vi.begin();
4. }
那个迭代器可以声明为:
1. autoci=vi.begin();
C++11也提供了从对象或表达式中“俘获”类型的机制,新的操作符decltype可以从一个表达式中“俘获”其结果的类型并“返回”:
1. constvector<int>vi;
2. typedefdecltype(vi.begin())CIT;
3. CITanother_const_iterator;
三、统一的初始化语法
C++最少有 4种不同的初始化形式,如括号内初始化,见:
1. std::strings("hello");
2. intm=int();//defaultinitialization
还有等号形式的:
1. std::strings="hello";
2. intx=5;
对于 POD集合,又可以用大括号:
1. intarr[4]={0,1,2,3};
2. structtmtoday={0};
最后还有构造函数的成员初始化:
1. structS{
【C++11标准库新加功能详解】2. intx;
3. S():x(0){}};
这么多初始化形式,不仅菜鸟会搞得很头大,高手也吃不消 。更惨的是 C++03中居然不能初始化POD数组的类成员,也不能在使用 new[]的时候初始 POD数组!C++11就用大括号一统天下了:
1. classC
2. {
3. inta;
4. intb;
5. public:
6. C(inti,intj);
7. };
8. Cc{0,0};//C++11only.相当于Cc(0,0);
9. int*a=newint[3]{1,2,0};/C++11only
10. classX{
11. inta[4];
12. public:
13. X():a{1,2,3,4}{}//C++11,初始化数组成员
14. };
还有一大好事就是对于容器来说,终于可以摆脱push_back()调用了,C++11中可以直观地初始化容器了:
1. //C++11containerinitializer
2. vectorvs<string>={"first","second","third"};
3. mapsingers=
4. {{"LadyGaga","+1(212)555-7890"},
5. {"BeyonceKnowles","+1(212)555-0987"}};
而类中的数据成员初始化也得到了支持:
1. classC
2. {
3. inta=7;//C++11only
4. public:
5. C();
6. };
四.deleted函数和 defaulted函数
像以下形式的函数:
1. structA
2. {
3. A()=default;//C++11
4. virtual~A()=default;//C++11
5. };
叫做 defaulted函数,=default;指示编译器生成该函数的默认实现 。这有两个好处:一是让程序员轻松了,少敲键盘,二是有更好的性能 。
与 defaulted函数相对的就是 deleted函数:
1. intfunc()=delete;
这货有一大用途就是实现 noncopyabe防止对象拷贝,要想禁止拷贝,用 =deleted声明一下两个关键的成员函数就可以了:
structNoCopy
{
NoCopy&operator=(constNoCopy&)=delete;
NoCopy(constNoCopy&)=delete;
};
NoCopya;
NoCopyb(a);//编译错误,拷贝构造函数是deleted函数
nullptr
nullptr是一个新的 C++关键字,它是空指针常量,它是用来替代高风险的 NULL宏和 0字面量的 。nullptr是强类型的:
voidf(int);//#1
voidf(char*);//#2
//C++03
f(0);//调用的是哪个f?
//C++11
f(nullptr)//毫无疑问,调用的是#2
所有跟指针有关的地方都可以用nullptr,包括函数指针和成员指针:
constchar*pc=str.c_str();//datapointers
if(pc!=nullptr)
cout<<pc<<endl;
int(A::*pmf)()=nullptr;//指向成员函数的指针
void(*pmf)()=nullptr;//指向函数的指针


推荐阅读