【C++】C++11 新特性(auto,decltype,nullptr,快速遍历,【Lambda表达式详解】)
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表达式详解】)相关推荐
- java lambda表达式详解_Java8新特性Lambda表达式详解
课程目标: 通过本课程的学习,详细掌握Java8新特性之Lambda表达式: 适用人群:有Java基础的开发人员: 课程概述:从Java 8出现以来lambda是最重要的特性之一,它可以让我们用简洁流 ...
- C++11新特性之decltype类型推导
目录 一.decltype关键字 二.decltype的推导规则 1.表达式为单独变量 2.表达式为函数调用 3.表达式为左值,或者被()包围 三. decltype的应用 在前面一章,小编已经对 ...
- C++11新特性——λ(lambda)表达式详解
C++11新特性--λ(lambda)表达式 C++11中引入了λ表达式,它可以用来定义一个内联(inline)的函数,作为一个本地的对象或者一个参数.有了λ表达式,我们可以很方便的使用stl标准库. ...
- 二、C++11新特性:decltype类型推导
目录 二.decltype类型推导 2.1. decltype decltype和auto的异同: 2.2.decltype的应用 ①.decltype和typedf/using合用 ②.deltyp ...
- C++11新特性之decltype关键字的使用
一.decltype关键字介绍 decltype关键字与auto关键字相似,但又有不同之处:auto关键字是在编译时通过已经初始化的变量来确定auto所代表的类型.换句话说,auto修饰的表达式必须是 ...
- jdk8新特性 lambda表达式详解
本文主要讲到的内容有: 一- 前言 二- 背景 三- lambda表达式的语法 四- Lambda程序例子 4-1 Runnable Lambda 4-2 Comparator Lambda 4-3 ...
- java lambda表达式详解_Java8新特性:Lambda表达式详解
在 Java 版本的历次更新迭代中,Java8 是一个特殊的存在,与以往的版本升级不同.我们对 Java8 似乎抱有更大的期待,因为它是 Java5 之后最重要的一次升级,提供了十多个新特性,其中 L ...
- java lambda表达式详解_java8新特性-Lambda表达式的详解(从0开始)
这几天复习了java8的一些新特性,作为一个从java5以来最具革命性的版本,一直没有来得及总结.本系列文章主要是从<java8实战>总结的.这是第一篇文章主要介绍java8的lambda ...
- C++11新特性——auto和decltype
一.auto和decltype 1.auto和decltype都是C++11新增的关键字,都用于类型自动推导. 类型格式 auto varname = value; //auto的语法格式 declt ...
最新文章
- Python,OpenCV中的图像修复——cv2.inpaint()
- python的HTML文件中使用和加载CSS文件
- iis worker process cpu 高_egg中的master、worker和agent
- 使用NTDSXtract离线抓取Domain Hash
- 开源ImageFilter库v0.3:新增22种图片效果
- [导入]第 3 章 Enterprise Library 的设计
- HTML、CSS 和 JS框架之Bootstrap
- 导入时间过长,请求变成404,导入成功后后台会出现java.io.IOException: 您的主机中的软件中止了一个已建立的连接
- 离线安装宝塔lnmp_宝塔LNMP环境 Nginx安装EduSoho教程说明
- display和show的区别
- LeetCode 1380. 矩阵中的幸运数(set)
- mysql索引为啥要选择B+树 (下)
- php htmlspecialchars 不管用,php5.4以上版本GBK编码下htmlspecialchars输出为空问题解决方法汇总_php技巧...
- sitemap.xml生成方法(asp和php)(转)
- Unity3D中背景音乐和相关音效的添加,背景音乐暂停、停止和播放的设置
- win10无线断开无法连接服务器,简单几步解决win10wifi一直断开连接不上的问题
- Bagging和Boosting(偏差与方差)
- win10系统的定位服务器,系统大神教你Win10笔记本电脑定位跟踪功能技巧
- AtCoder Regular Contest 105 C - Camels and Bridge
- 服务器上引用不了js文件,pdf.js不通过服务器如何像普通js文件引入使用