C++11 重要新特性

  • auto
  • decltype
  • nullptr
  • 快速遍历与数组初始化
  • Lambda 表达式
    • Lambda 应用
    • 外部变量捕获
    • mutable

auto

  • 可以从初始化表达式中推断出变量的类型,大大简化编程工作
  • 属于编译器特性,不影响最终的机器码质量,不影响运行效率
#include <iostream>
#include <typeinfo>
using namespace std;class Person {};int main() {// auto 可以根据变量值自动推断变量类型,且不影响运行效率auto i = 10; // intcout << typeid(i).name() << endl;auto j = 10.0; // doublecout << typeid(j).name() << endl;auto str = "c++"; // const char *cout << typeid(str).name() << endl;auto p = new Person(); // Person *cout << typeid(p).name() << endl;return 0;
}
int
double
char const *
class Person *

decltype

  • 可以获取变量的类型
int a = 10;
decltype(a) b = 20; // intPerson *p = new Person();
decltype(p) p2; // Person*

nullptr

  • 解决了 NULL 的二义性问题

所谓二义性,见如下代码。

#include<iostream>
using namespace std;void func(int v) {cout << "func(int)" << endl;
}
void func(int *p) {cout << "func(int *)" << endl;
}
int main() {// C++98中会报错,当时 NULL 既代表空指针又代表 0,具有二义性func(NULL);       // func(int)// C++11出现了 nullptr, 并且 NULL==0, 解决了二义性func(nullptr);  // func(int *)
}
func(int)
func(int *)

按住 ctrl + 鼠标左键 点击 NULL,查看 C++ 源码可以发现:
C++ 中的 NULL 实际上是个宏定义,并且被定义为 0

常见的空指针写法 int *p = NULL; 源于C++98。
C++11 以后建议使用 nullptr 表示空指针int *p = nullptr 更好。

快速遍历与数组初始化

#include<iostream>
using namespace std;int main() {// int array[] = { 11, 22, 33, 44, 55 }; 与下面完全一样int array[]{11, 22, 33, 44, 55}; // 更加简洁的初始方式,语法糖for (int item : array) { // 快速遍历cout << item << endl;}return 0;
}
11
22
33
44
55

Lambda 表达式

  • Lambda 表达式的本质就是函数

完整结构(还是结合代码更好理解)
[capture list] (params list) mutable exception-> return type {function body}

  • capture list:捕获外部变量列表
  • params list:形参列表,不能使用默认参数,不能省略参数名
  • mutable:用来说用是否可以修改捕获的变量
  • exception:异常设定
  • return type:返回值类型
  • function body:函数体

有时可以省略部分结构,形式更简洁

  • [capture list] (params list) -> return type {function body}
  • [capture list] (params list) {function body}
  • [capture list] {function body}

首先来一个形式最简单的 Lambda 表达式,注意,Lambda 表达式很多结构可以省略,C++中 []中括号是 Lambda 的标志,绝对不可省略。

#include<iostream>
using namespace std;int main() {// 这是形式最简单的 lambda 表达式// [capture list] {function body}[] {cout << "Hello World" << endl; };// 运行后没有任何结果return 0;
}

实际上这么写并没有运行结果,因为根本没有调用函数。调用这个最简单的 Lambda 表达式方法如下:

int main() {// 调用形式最简单的 lambda 表达式,"()()"([] {cout << "Hello World" << endl;})();// 输出 Hello Worldreturn 0;
}
Hello World

没错,实际上就是写成了函数的形式 “()()”,很好记。

Lambda 表达式既然是个“表达式”,自然可以被赋值,示例如下:

#include<iostream>
using namespace std;int main() {// 函数指针的方式给 Lambda 表达式赋值int(*p) (int a, int b) = [](int a, int b) -> int {return a + b;};cout << p(10, 20) << endl;cout << p(20, 30) << endl;return 0;
}

可以简化一点,表达式后面的 -> int 可以不写,会自动判断返回类型。

int(*p) (int a, int b) = [](int a, int b) {return a + b;
};

既然 C++11 出现了 auto ,实际上更推荐这么写(更简洁):

#include<iostream>
using namespace std;int main() {// auto 自动判断类型,使用起来很方便// 并且前面不需要写参数auto p = [] (int a, int b) {return a + b;};cout << p(10, 20) << endl;cout << p(20, 30) << endl;return 0;
}

Lambda 应用

不使用 Lambda 写一个 +,-,*,/ 可能是这么写的:

#include<iostream>
using namespace std;int add(int v1, int v2) {return v1 + v2;
}
int sub(int v1, int v2) {return v1 - v2;
}
int multiply(int v1, int v2) {return v1 * v2;
}
int divide(int v1, int v2) {return v1 / v2;
}
// 函数指针
auto exec(int v1, int v2, int(*func)(int, int)) {return func(v1, v2);
}int main() {cout << exec(20, 10, add) << endl;cout << exec(20, 10, sub) << endl;cout << exec(20, 10, multiply) << endl;cout << exec(20, 10, divide) << endl;
}
30
10
200
2

使用了 Lambda 后就变成这样了:

#include<iostream>
using namespace std;// 函数指针
auto exec(int v1, int v2, int(*func)(int, int)) { if (func == nullptr) return 0;return func(v1, v2);
}int main() {cout << exec(20, 10, [](int v1, int v2) {return v1 + v2; }) << endl;cout << exec(20, 10, [](int v1, int v2) {return v1 - v2; }) << endl;cout << exec(20, 10, [](int v1, int v2) {return v1 * v2; }) << endl;cout << exec(20, 10, [](int v1, int v2) {return v1 / v2; }) << endl;
}

外部变量捕获

#include<iostream>
using namespace std;int main() {int a = 10;int b = 20;// 值捕获auto func = [a, b] {cout << a << endl;cout << b << endl;};a = 11;b = 22;// Lambda 只捕获了a,b的值,后面的外面的变化与他无关func(); // 10 20
}
10
20
#include<iostream>
using namespace std;int main() {int a = 10;int b = 20;// 隐式捕获(值捕获)auto func = [=] { // 使用 = 自动捕获用到的参数cout << a << endl;cout << b << endl;};a = 11;b = 22;func(); // 10 20
}
10
20
#include<iostream>
using namespace std;int main() {int a = 10;int b = 20;// a是引用(地址)捕获,b是指捕获auto func = [&a, b] { // 使用 = 自动捕获用到的参数cout << a << endl;cout << b << endl;};a = 11;b = 22;func(); // 11 20
}
11
20
#include<iostream>
using namespace std;int main() {int a = 10;int b = 20;// a是值捕获,其余变量是地址捕获auto func = [&, a] { // 使用 = 自动捕获用到的参数cout << a << endl;cout << b << endl;};a = 11; b = 22;func(); // 10 22
}
10
22
#include<iostream>
using namespace std;int main() {int a = 10;int b = 20;// 隐式捕获(值捕获)auto func = [&] { // 使用 = 自动捕获用到的参数cout << a << endl;cout << b << endl;};a = 11; b = 22;func(); // 11 22
}
11
22

一张图总结如下。。。

mutable

#include<iostream>
using namespace std;int main() {int a = 10; auto func = [a]()mutable {cout << ++a << endl;};func(); //11cout << a << endl; //10
}
11
10

【C++】C++11 新特性(auto,decltype,nullptr,快速遍历,【Lambda表达式详解】)相关推荐

  1. java lambda表达式详解_Java8新特性Lambda表达式详解

    课程目标: 通过本课程的学习,详细掌握Java8新特性之Lambda表达式: 适用人群:有Java基础的开发人员: 课程概述:从Java 8出现以来lambda是最重要的特性之一,它可以让我们用简洁流 ...

  2. C++11新特性之decltype类型推导

    ​ 目录 一.decltype关键字 二.decltype的推导规则 1.表达式为单独变量 2.表达式为函数调用 3.表达式为左值,或者被()包围 三. decltype的应用 在前面一章,小编已经对 ...

  3. C++11新特性——λ(lambda)表达式详解

    C++11新特性--λ(lambda)表达式 C++11中引入了λ表达式,它可以用来定义一个内联(inline)的函数,作为一个本地的对象或者一个参数.有了λ表达式,我们可以很方便的使用stl标准库. ...

  4. 二、C++11新特性:decltype类型推导

    目录 二.decltype类型推导 2.1. decltype decltype和auto的异同: 2.2.decltype的应用 ①.decltype和typedf/using合用 ②.deltyp ...

  5. C++11新特性之decltype关键字的使用

    一.decltype关键字介绍 decltype关键字与auto关键字相似,但又有不同之处:auto关键字是在编译时通过已经初始化的变量来确定auto所代表的类型.换句话说,auto修饰的表达式必须是 ...

  6. jdk8新特性 lambda表达式详解

    本文主要讲到的内容有: 一- 前言 二- 背景 三- lambda表达式的语法 四- Lambda程序例子 4-1 Runnable Lambda 4-2 Comparator Lambda 4-3 ...

  7. java lambda表达式详解_Java8新特性:Lambda表达式详解

    在 Java 版本的历次更新迭代中,Java8 是一个特殊的存在,与以往的版本升级不同.我们对 Java8 似乎抱有更大的期待,因为它是 Java5 之后最重要的一次升级,提供了十多个新特性,其中 L ...

  8. java lambda表达式详解_java8新特性-Lambda表达式的详解(从0开始)

    这几天复习了java8的一些新特性,作为一个从java5以来最具革命性的版本,一直没有来得及总结.本系列文章主要是从<java8实战>总结的.这是第一篇文章主要介绍java8的lambda ...

  9. C++11新特性——auto和decltype

    一.auto和decltype 1.auto和decltype都是C++11新增的关键字,都用于类型自动推导. 类型格式 auto varname = value; //auto的语法格式 declt ...

最新文章

  1. Python,OpenCV中的图像修复——cv2.inpaint()
  2. python的HTML文件中使用和加载CSS文件
  3. iis worker process cpu 高_egg中的master、worker和agent
  4. 使用NTDSXtract离线抓取Domain Hash
  5. 开源ImageFilter库v0.3:新增22种图片效果
  6. [导入]第 3 章 Enterprise Library 的设计
  7. HTML、CSS 和 JS框架之Bootstrap
  8. 导入时间过长,请求变成404,导入成功后后台会出现java.io.IOException: 您的主机中的软件中止了一个已建立的连接
  9. 离线安装宝塔lnmp_宝塔LNMP环境 Nginx安装EduSoho教程说明
  10. display和show的区别
  11. LeetCode 1380. 矩阵中的幸运数(set)
  12. mysql索引为啥要选择B+树 (下)
  13. php htmlspecialchars 不管用,php5.4以上版本GBK编码下htmlspecialchars输出为空问题解决方法汇总_php技巧...
  14. sitemap.xml生成方法(asp和php)(转)
  15. Unity3D中背景音乐和相关音效的添加,背景音乐暂停、停止和播放的设置
  16. win10无线断开无法连接服务器,简单几步解决win10wifi一直断开连接不上的问题
  17. Bagging和Boosting(偏差与方差)
  18. win10系统的定位服务器,系统大神教你Win10笔记本电脑定位跟踪功能技巧
  19. AtCoder Regular Contest 105 C - Camels and Bridge
  20. 服务器上引用不了js文件,pdf.js不通过服务器如何像普通js文件引入使用

热门文章

  1. Speaking of the impact of the epidemic
  2. Qt——P13 Q4版本信号槽连接
  3. P3 吴恩达推荐笔记:22张图总结深度学习全部知识
  4. 解决VMWare虚拟机IP变成127.0.0.1和选择固定IP段
  5. Sentinel总结(个人笔记)
  6. TCP/IP参考模型和五层参考模型
  7. @sql 单元测试_10个最常见SQL单元测试错误
  8. 让您的数据库服务器与您对话:直接从SQL Agent Jobs发送电子邮件
  9. 数据结构:判断是否为同一棵二叉搜索树
  10. 洛谷 P2056 采花