C++ Primer Chapter 10 Generic Algorithms

Chapter 10 Generic Algorithms

10.3 定制操作

10.3.2 lambda 表达式

介绍lambda

可调用对象(callable object)

对于一个对象或一个表达式,如果对其使用调用运算符,则称它为可调用的。

即,如果e是一个可调用的表达式,则我们可以编写代码e(args),其中args是一个逗号分隔的一个或多个参数的列表。

lambda表达式(lambda expression)

一个lambda表达式表示一个可调用的代码单元。我们可以将其理解为一个未命名的内联函数。与任何函数类似,一个lambda具有一个返回类型、一个参数列表和一个函数体。但与函数不同,lambda可能定义在函数内部。

一个lambda表达式具有如下形式

复制代码
[capture list] (parameter list)->return type	{ function body }

其中,capture list(捕获列表)是一个lambda所在函数中定义的局部变量的列表(通常为空);return type、parameter list和function body与任何普通函数一样,分别表示返回类型、参数列表和函数体。单数,与普通函数不同,lambda必须使用尾置返回来指定返回类型。

10.3.3 lambda捕获和返回

当定义一个lambda时,编译器生成了一个与lambda对应的新的(未命名的)类类型。

当向一个函数传递一个lambda时,同时定义了一个新类型和该类型的一个对象:传递的参数就是此编译器生成的类类型的未命名对象。

类似的,当使用auto定义一个用lambda初始化的变量时,定义了一个从lambda生成的类型的对象。

默认情况下,从lambda生成的类都包含一个对应该lambda所捕获的变量的数据成员。类似任何普通类的数据成员,lambda的数据成员也在lambda对象创建时被初始化。

值捕获

与参数不同,被捕获的变量的值是在lambda创建时拷贝,而不是调用时拷贝:

cpp 复制代码
void fcn1()
{
	size_t v1=42;		//局部变量
	//将v1拷贝到名为f的可调用对象
	auto f=[v1] {return v1;};
	v1=0;
	auto j=f();			//j为42;f保存了我们创建它时v1的拷贝
}

引用捕获

cpp 复制代码
void fcn2()
{
	size_t v1=42;		//局部变量
	//将v1拷贝到名为f的可调用对象
	auto f2=[&v1] {return v1;};
	v1=0;
	auto j=f();			//j为0;f2保存v1的引用,而非拷贝
}

WARNNING 当以引用方式捕获一个变量时,必须保证在lambda执行时变量是存在的。

隐式捕获

除了显式列出我们希望使用的来自所在函数的变量之外,还可以让编译器根据lambda体中的代码来推断我们要使用那些变量。为了指示编译器推断捕获列表,应在捕获列表中写一个&或=。&告诉编译器采用捕获引用方式,=则表示采用值捕获方式。

如果我们希望对一部分变量采用值捕获,对其他变量采用引用捕获,可以混合使用隐式捕获和显式捕获:

相关推荐
雨落倾城夏未凉25 分钟前
8.被free回收的内存是立即返还给操作系统吗?为什么?
c++·后端
雨落倾城夏未凉28 分钟前
6.new和malloc的区别
c++·后端
郝学胜-神的一滴32 分钟前
深入理解QFlags:Qt中的位标志管理工具
开发语言·c++·qt·程序人生
INS_KF1 小时前
【C++知识杂记2】free和delete区别
c++·笔记·学习
一只鱼^_2 小时前
牛客周赛 Round 105
数据结构·c++·算法·均值算法·逻辑回归·动态规划·启发式算法
ikkkkkkkl2 小时前
C++设计模式:面向对象设计原则
c++·设计模式·面向对象
啊阿狸不会拉杆2 小时前
《算法导论》第 27 章 - 多线程算法
java·jvm·c++·算法·图论
重启的码农2 小时前
ggml介绍 (8) 图分配器 (ggml_gallocr)
c++·人工智能·神经网络
重启的码农2 小时前
ggml介绍 (9) 后端调度器 (ggml_backend_sched)
c++·人工智能·神经网络
汉汉汉汉汉4 小时前
C++11新特性详解:从列表初始化到线程库
c++