龙空技术网

C++ 之 Lambda 表达式

算法集市 1745

前言:

而今同学们对“stl算法函数”大体比较关心,你们都想要知道一些“stl算法函数”的相关内容。那么小编也在网上收集了一些关于“stl算法函数””的相关内容,希望兄弟们能喜欢,同学们快快来了解一下吧!

C++11标准中引入了 Lambda 表达式,用于定义匿名函数,使得代码更加灵活简洁。

Lambda 表达式与普通函数类似,也有参数列表、返回值类型和函数体,只是它的定义方式更简洁,并且可以在函数内部定义。

下面是一个简单的例子,用于计算两数之和。

auto plus = [] (int x, int x) -> int { return x + y; }int sum = plus(1, 2);

一般情况下 Lambda 表达式不会这样使用的,而是和 STL 的一些算法结合使用。

1、Lambda 表达式示例

比如,生成一个 vector,里面是随机数,一种是使用常规函数 my_rand(),如下图所示。

其中,std::generate() 是一种 STL 算法,用于根据生成器函数生成数字,然后将这些值放到容器中。

void generate (ForwardIterator first, ForwardIterator last, Generator gen);first: Forward iterator pointing to the first element of the container.last: Forward iterator pointing to the last element of the container.gen: A generator function, based upon which values will be assigned.

另外一种是使用 Lambda 表达式,如下图所示。

可以看出,Lambda 表达式让函数对象定义在调用的地方。

相比常规函数,Lambda 表达式可以直接看到上下文,让代码更加简洁、清晰,可读性更强,如果需要修改代码,涉及的内容就在附近。

2、Lambda 表达式访问外部变量

C++ 11 中的 Lambda 表达式用于定义并创建匿名的函数对象,以简化编程工作。

Lambda 语法形式如下:

[captures](params) -> return_type { body };

Lambda 主要分为五个部分,对应为:

[捕获列表] (函数参数) mutable 或 exception 声明 -> 返回值类型 {函数体}

捕获列表是 Lambda 表达式最有意思的地方,这里重点介绍下捕获列表。

捕获列表,用来说明外部变量的访问方式,外部变量访问方式说明符可以是 = 或 & ,表示函数体中用到的、定义在外面的变量在函数体中是否允许被改变。= 表示值传递,不允许改变。& 表示引用传递,允许改变。

包括下面几种形式:

[ ] 表示不捕获任何变量[=] 表示按值传递的方法捕获父作用域的所有变量[&] 表示按引用传递的方法捕获父作用域的所有变量[=, &a] 表示按值传递的方法捕获父作用域的所有变量,但按引用传递的方法捕获变量a[&, a] 表示按引用传递的方法捕获父作用域的所有变量,但按值传递的方法捕获变量a

比如要统计 vec 内能被 2 整除的变量的个数,一种是调用 std::count_if() ,一种是使用 Lambda 的引用捕获 [&],如下图所示,在 Lambda 表达式中可以直接修改变量 n2。

上图中,std::count_if() 函数来计算容器中符合条件的元素有多少个,std::for_each() 函数用来逐个遍历容器元素,并执行由单参数函数对象所定义的操作。

综上,使用 Lambda 表达式的两点优势:

一是函数对象定义在调用的地方,直接看到上下文,可读性更强,方便修改;二是 Lambda 表达式可访问作用域内的任何变量,代码简洁。

当然,使用 Lambda 表达式的前提是 函数体足够简单,只有一两行。当函数体复杂时,还是推荐使用常规函数。

标签: #stl算法函数