C++ 中的Lambda表达式写法

2020-01-06 16:37:34王冬梅

运行的结果:

其实函数也可以当参数传入的(函数指针),但是lambda表达式要更为直观和灵活一些。谁能一眼看出int (*func(int))(int)究竟是什么意思呢(这是一个函数的定义,输入的参数是int,返回值是一个函数指针,函数指针对应的函数的输入和输出类型都是int)。

三、Lambda表达式的语法

看到前面的lambda表达式的各种有趣的功能,现在是不是非常迫切的想尝试一把?

ISO C++ 标准展示了作为第三个参数传递给 std::sort() 函数的简单 lambda:


#include <algorithm> 
#include <cmath> 
 
void abssort(float* x, unsigned n) { 
 std::sort(x, x + n, 
  // Lambda expression begins 
  [](float a, float b) { 
   return (std::abs(a) < std::abs(b)); 
  } // end of lambda expression 
 ); 
}

lambda表达式的组成部分见下图:

c++,lambda表达式

Capture 子句(在 C++ 规范中也称为 lambda 引导。)

参数列表(可选)。 (也称为 lambda 声明符)

可变规范(可选)。

异常规范(可选)。

尾随返回类型(可选)。

“lambda 体”

接下来我们需要学习这6个部分。

1、Capture 子句

我们知道,一般情况下,函数只能访问自己的参数和外部的全局变量。而lambda表达式却可以访问上下文的变量(参见闭包的例子)。那么如何指定要访问的变量,以及访问的方式(值或者引用)呢?这就是Capture 子句要解决的问题。

Lambda 可在其主体中引入新的变量(用 C++14),它还可以访问(或 “捕获” )周边范围内的变量。 Lambda 以 Capture 子句(标准语法中的  lambda 引导 )开头,它指定要捕获的变量以及是通过值还是引用进行捕获。 有与号 ( & ) 前缀的变量通过引用访问,没有该前缀的变量通过值访问。

空 capture 子句 [ ] 指示 lambda 表达式的主体不访问封闭范围中的变量。

可以使用默认捕获模式(标准语法中的 capture-default )来指示如何捕获 lambda 中引用的任何外部变量:[&] 表示通过引用捕获引用的所有变量,而 [=] 表示通过值捕获它们。 可以使用默认捕获模式,然后为特定变量显式指定相反的模式。 例如,如果 lambda 体通过引用访问外部变量  total 并通过值访问外部变量  factor ,则以下 capture 子句等效:

[&total, factor] 
[factor, &total] 
[&, factor] 
[factor, &] 
[=, &total] 
[&total, =]

我们之前的闭包中使用的就是通过值访问。

使用 capture-default 时,只有 lambda 中提及的变量才会被捕获。