Lambda 表达式

Lambda 表达式的形式是这样的:

view plaincopy to clipboardprint?
  1. [capture](parameters)->return-type {body}

[capture](parameters)->return-type {body}
来看个计数某个字符序列中有几个大写字母的例子:

view plaincopy to clipboardprint?
  1. int main()
  2. {
  3. char s[]="Hello World!";
  4. int Uppercase = 0; //modified by the lambda
  5. for_each(s, s+sizeof(s), [&Uppercase] (char c) {
  6. if (isupper(c))
  7. Uppercase++;
  8. });
  9. cout<< Uppercase<<" uppercase letters in: "<< s<<endl;
  10. }

int main() { char s[]="Hello World!"; int Uppercase = 0; //modified by the lambda for_each(s, s+sizeof(s), [&Uppercase] (char c) { if (isupper(c)) Uppercase++; }); cout<< Uppercase<<" uppercase letters in: "<< s<<endl; }
其中 [&Uppercase] 中的 & 的意义是 lambda 函数体要获取一个 Uppercase 引用,以便能够改变它的值,如果没有 &,那就 Uppercase 将以传值的形式传递过去。

自动类型推导和 decltype

在 C++03 中,声明对象的同时必须指明其类型,其实大多数情况下,声明对象的同时也会包括一个初始值,C++11 在这种情况下就能够让你声明对象时不再指定类型了:

view plaincopy to clipboardprint?
  1. auto x=0; //0 是 int 类型,所以 x 也是 int 类型
  2. auto c='a'; //char
  3. auto d=0.5; //double
  4. auto national_debt=14400000000000LL;//long long

auto x=0; //0 是 int 类型,所以 x 也是 int 类型 auto c='a'; //char auto d=0.5; //double auto national_debt=14400000000000LL;//long long
这个特性在对象的类型很大很长的时候很有用,如:

view plaincopy to clipboardprint?
  1. void func(const vector<int> &vi)
  2. {
  3. vector<int>::const_iterator ci=vi.begin();
  4. }

void func(const vector<int> &vi) { vector<int>::const_iterator ci=vi.begin(); }
那个迭代器可以声明为:

view plaincopy to clipboardprint?
  1. auto ci=vi.begin();

auto ci=vi.begin();
C++11 也提供了从对象或表达式中“俘获”类型的机制,新的操作符 decltype 可以从一个表达式中“俘获”其结果的类型并“返回”:

view plaincopy to clipboardprint?
  1. const vector<int> vi;
  2. typedef decltype (vi.begin()) CIT;
  3. CIT another_const_iterator;

const vector<int> vi; typedef decltype (vi.begin()) CIT; CIT another_const_iterator;

统一的初始化语法

C++ 最少有 4 种不同的初始化形式,如括号内初始化,见:

view plaincopy to clipboardprint?
  1. std::string s("hello");
  2. int m=int(); //default initialization

std::string s("hello"); int m=int(); //default initialization
还有等号形式的:

view plaincopy to clipboardprint?
  1. std::string s="hello";
  2. int x=5;

std::string s="hello"; int x=5;
对于 POD 集合,又可以用大括号:

view plaincopy to clipboardprint?
  1. int arr[4]={0,1,2,3};
  2. struct tm today={0};

int arr[4]={0,1,2,3}; struct tm today={0};
最后还有构造函数的成员初始化:

view plaincopy to clipboardprint?
  1. struct S {
  2. int x;
  3. S(): x(0) {} };

struct S { int x; S(): x(0) {} };
这么多初始化形式,不仅菜鸟会搞得很头大,高手也吃不消。更惨的是 C++03 中居然不能初始化 POD 数组的类成员,也不能在使用 new[] 的时候初始 POD 数组,操蛋啊!C++11 就用大括号一统天下了:

view plaincopy to clipboardprint?
  1. class C
  2. {
  3. int a;
  4. int b;
  5. public:
  6. C(int i, int j);
  7. };
  8. C c {0,0}; //C++11 only. 相当于 C c(0,0);
  9. int* a = new int[3] { 1, 2, 0 }; /C++11 only
  10. class X {
  11. int a[4];
  12. public:
  13. X() : a{1,2,3,4} {} //C++11, 初始化数组成员
  14. };

class C { int a; int b; public: C(int i, int j); }; C c {0,0}; //C++11 only. 相当于 C c(0,0); int* a = new int[3] { 1, 2, 0 }; /C++11 only class X { int a[4]; public: X() : a{1,2,3,4} {} //C++11, 初始化数组成员 };
还有一大好事就是对于容器来说,终于可以摆脱 push_back() 调用了,C++11中可以直观地初始化容器了:

view plaincopy to clipboardprint?
  1. // C++11 container initializer
  2. vector vs<string>={ "first", "second", "third"};
  3. map singers =
  4. { {"Lady Gaga", "+1 (212) 555-7890"},
  5. {"Beyonce Knowles", "+1 (212) 555-0987"}};

// C++11 container initializer vector vs<string>={ "first", "second", "third"}; map singers = { {"Lady Gaga", "+1 (212) 555-7890"}, {"Beyonce Knowles", "+1 (212) 555-0987"}};
而类中的数据成员初始化也得到了支持:

view plaincopy to clipboardprint?
  1. class C
  2. {
  3. int a=7; //C++11 only
  4. public:
  5. C();
  6. };

class C { int a=7; //C++11 only public: C(); };

deleted 函数和 defaulted 函数

像以下形式的函数:

view plaincopy to clipboardprint?
  1. struct A
  2. {
  3. A()=default; //C++11
  4. virtual ~A()=default; //C++11
  5. };

struct A { A()=default; //C++11 virtual ~A()=default; //C++11 };
叫做 defaulted 函数,=default; 指示编译器生成该函数的默认实现。这有两个好处:一是让程序员轻松了,少敲键盘,二是有更好的性能。
与 defaulted 函数相对的就是 deleted 函数:

view plaincopy to clipboardprint?
  1. int func()=delete;

int func()=delete;
这货有一大用途就是实现 noncopyabe 防止对象拷贝,要想禁止拷贝,用 =deleted 声明一下两个关键的成员函数就可以了:

view plaincopy to clipboardprint?
  1. struct NoCopy
  2. {
  3. NoCopy & operator =( const NoCopy & ) = delete;
  4. NoCopy ( const NoCopy & ) = delete;
  5. };
  6. NoCopy a;
  7. NoCopy b(a); //编译错误,拷贝构造函数是 deleted 函数

struct NoCopy { NoCopy & operator =( const NoCopy & ) = delete; NoCopy ( const NoCopy & ) = delete; }; NoCopy a; NoCopy b(a); //编译错误,拷贝构造函数是 deleted 函数

nullptr

nullptr 是一个新的 C++ 关键字,它是空指针常量,它是用来替代高风险的 NULL 宏和 0 字面量的。nullptr 是强类型的:

view plaincopy to clipboardprint?
  1. void f(int); //#1
  2. void f(char *);//#2
  3. //C++03
  4. f(0); //调用的是哪个 f?
  5. //C++11
  6. f(nullptr) //毫无疑问,调用的是 #2

void f(int); //#1 void f(char *);//#2 //C++03 f(0); //调用的是哪个 f? //C++11 f(nullptr) //毫无疑问,调用的是 #2
所有跟指针有关的地方都可以用 nullptr,包括函数指针和成员指针:

view plaincopy to clipboardprint?
  1. const char *pc=str.c_str(); //data pointers
  2. if (pc!=nullptr)
  3. cout<<pc<<endl;
  4. int (A::*pmf)()=nullptr; //指向成员函数的指针
  5. void (*pmf)()=nullptr; //指向函数的指针

const char *pc=str.c_str(); //data pointers if (pc!=nullptr) cout<<pc<<endl; int (A::*pmf)()=nullptr; //指向成员函数的指针 void (*pmf)()=nullptr; //指向函数的指针

委托构造函数

C++11 中构造函数可以调用同一个类的另一个构造函数:   http://www.xmhlweb.com/

view plaincopy to clipboardprint?
  1. class M //C++11 delegating constructors
  2. {
  3. int x, y;
  4. char *p;
  5. public:
  6. M(int v) : x(v), y(0),  p(new char [MAX])  {} //#1 target
  7. M(): M(0) {cout<<"delegating ctor"<<end;} //#2 delegating

class M //C++11 delegating constructors { int x, y; char *p; public: M(int v) : x(v), y(0), p(new char [MAX]) {} //#1 target M(): M(0) {cout<<"delegating ctor"<<end;} //#2 delegating
#2 就是所谓的委托构造函数,调用了真正的构造函数 #1。

右值引用

在 C++03 中的引用类型是只绑定左值的,C++11 引用一个新的引用类型叫右值引用类型,它是绑定到右值的,如临时对象或字面量。    http://www.xmhlweb.com/
增加右值引用的主要原因是为了实现 move 语义。与传统的拷贝不同,move 的意思是目标对象“窃取”原对象的资源,并将源置于“空”状态。当拷贝一个对象时,其实代价昂贵且无必要,move 操作就可以替代它。如在 string 交换的时候,使用 move 意义就有巨大的性能提升,如原方案是这样的:

转载于:https://www.cnblogs.com/wxinmylife/archive/2011/10/29/2228463.html

C++11中值得关注的几大变化 .相关推荐

  1. C++11中值得关注的几大变化

    赖勇浩(http://laiyonghao.com) 声明:本文源自 Danny Kalev 在 2011 年 6 月 21 日发表的<The Biggest Changes in C++11( ...

  2. C++11 中值得关注的几大变化

    2019独角兽企业重金招聘Python工程师标准>>> 源文章来自前C++标准委员会的 Danny Kalev 的 The Biggest Changes in C++11 (and ...

  3. Go 1.8中值得关注的几个变化

    http://studygolang.com/articles/9298 本文来自:Tony Bai 感谢作者:bigwhite 查看原文:Go 1.8中值得关注的几个变化 在已经过去的2016年,G ...

  4. Go 1.16中值得关注的几个变化

    辛丑牛年初七开工大吉的日子(2021.2.18),Go核心开发团队为中国Gopher们献上了大礼 - Go 1.16版本正式发布了[1]下载到Go 1.16在各个平台的安装包: 2020年双12,Go ...

  5. Go 1.9中值得关注的几个变化

    原文地址:http://tonybai.com/ Go语言在2016年当选tiobe index的年度编程语言. 转眼间6个月过去了,Go在tiobe index排行榜上继续强势攀升,在最新公布的TI ...

  6. 【人工智能AI大数据】AI 的未来:ChatGPT 世界中值得关注的 4 大趋势

    AI 的未来:ChatGPT 世界中值得关注的 4 大趋势 The future of AI: 4 trends to watch for in a ChatGPT world 目录 AI 的未来:C ...

  7. 万字长文告诉你Go 1.19中值得关注的几个变化

    我们知道Go团队在2015年重新规定了团队发布版本的节奏,将Go大版本的发布频率确定为每年两次,发布窗口定为每年的2月与8月.而实现自举的Go 1.5版本[1]是这一个节奏下发布的第一个版本.一般来说 ...

  8. MySQL 8 中值得关注的新特性和改进

    1. 性能:读/写工作负载.IO 密集型工作负载.以及高竞争("hot spot"热点竞争问题)工作负载. 2. NoSQL:提供 NoSQL 存储功能,目前在 8.0 版本中更大 ...

  9. 今日互联网关注(写在清明节后):每天都有值得关注的大变化

     平时写文章除了写一些观点和专题,接下来最喜欢写的就是这种"关注类文章",原因如下: 1.不需要一个特定主题,不拘泥于某件事 2.无需特定文风,撰写很轻松 3.多日之后可以回过来再 ...

最新文章

  1. 将页面元素置为不可修改Readonly,所有元素统一修改,统一调用
  2. 算法笔记-归并算法面试题、逆序数问题
  3. 白盒测试工具_别再头疼工作效率低!这些超实用的黑盒、白盒测试方法你都用上了吗?...
  4. Java 集合系列(四)—— ListIterator 源码分析
  5. Node.js 安装报错提示“The error code is 2503“问题解决方法
  6. 全球及中国吉他霉素预混剂行业创新现状与可持续发展分析报告2022-2027年版
  7. Opportunity PRODUCT GUID
  8. 解决ubuntu下的firefox无法在线播放音频和视频的问题
  9. Ngnix的日志管理和用定时任务完成日志切割
  10. dubbo-Instantiation of bean failed; nested exception is java.lang.ExceptionInInitializerError
  11. 研究发现,近一半生产容器存在漏洞
  12. 利用python分析微信聊天记录
  13. developer.biao.daily.20140628
  14. 第四章:分支结构程序设计
  15. press ESC in 1 seconds to skip startup.nsh,any other key to continue
  16. Typora常用快捷键(仅记录常用功能)
  17. ajax实现数据库获取select二级联动下拉菜单
  18. 使用Rust开发编译系统(C以及Rust编译的过程)
  19. MD软件常见问题解答sp1版
  20. Line电脑版,whatsapp多开软件

热门文章

  1. thinkphp 框架自动加载原理_ThinkPHP5分析Part 1 基本框架流程
  2. 爬虫python编程与cvi编程_与爬虫无关,简单的用python进行科学运算
  3. linux查看服务器负载均衡,Linux服务器负载均衡LB
  4. 合并单元格两行_28 HTML5标签学习——table单元格的合并
  5. 军队可以用oracle,使用Oracle JRockit 提高tomcat性能
  6. C#调用C++ dll类型对照表汇总
  7. python多线程内存越要越大_Python 面试:这9个问题你一定要掌握!
  8. 0x80070003系统找不到指定路径_DeepFaceLab错误:DLL Load failed 找不到指定模块!
  9. im即时通讯源码_IM消息ID技术专题(六):深度解密滴滴的高性能ID生成器(Tinyid)
  10. 华为抢购助手_就一句话,华为这个智慧办公新物种“有点东西”!