什么是Lambda表达式

Lambda表达式是一种在被调用的位置作为参数传递给函数的位置定义匿名函数对象的方法。

Lambda表达式的基本语法如下:

1
[capture list](parameter list) -> return type {function body}

其中:

  • capture list是捕获列表,用于指定Lambda表达式内可访问的外部变量参数传递方式(传值还是引用)
    捕获列表可为空。
    默认捕获模式为&(引用类型)
  • parameter list是参数列表,和普通函数一样的使用方法。
    在C++14中使用auto关键字实现泛型返回值。
  • return type 返回值类型,同函数的返回值类型。需要使用“->”指出返回值类型,但也可以省略此时将由编译器推导。
    在C++14中使用auto关键字实现泛型返回值。
  • function body函数体用于表达表达式内的具体逻辑。
    在C++14中使用constexpr关键字实现编译期计算。

Lambda表达式的捕获方式

值捕获

值捕获在值改变时Lambda表达式不受影响。

1
2
3
4
5
int x = 10;
auto f = [x](int num) -> int {return x + num; };
std::cout << f(5) << std::endl; //输出:15
x = 20;
std::cout << f(5) << std::endl; //输出:15

引用捕获

引用捕获在引用的值改变时也将改变Lambda表达式中的值。

1
2
3
4
5
6
int x1 = 10;
int x2 = 10;
auto f = [x1,&x2](int num) -> int {return x1+x2+num; };
std::cout << f(5) << std::endl; //输出:25
x2 = 20;
std::cout << f(5) << std::endl; //输出:35

隐式捕获

当捕获列表比较长时,可以省略同一捕获类型的变量名称,使用=或&替代。

1
2
3
4
5
6
7
8
9
10
11
int x1 = 10;
int x2 = 10;
int x3 = 0;
auto f = [=,&x3,&x1](int num) -> int {return x1+x2+x3+num; };
//auto f = [&,x3,x1](int num) -> int {return x1+x2+x3+num; }; 合法的
//auto f = [&,&x3,x1](int num) -> int {return x1+x2+x3+num; }; 非法的
//auto f = [=,x3,&x1](int num) -> int {return x1+x2+x3+num; }; 非法的
std::cout << f(5) << std::endl; //输出:25
x2 = 20;
x3 = 40;
std::cout << f(5) << std::endl; //输出:65

初始化捕获 (C++14 引入的一种新的捕获方式)

在捕获列表中使用初始化表达式,从而在捕获列表中创建并初始化一个新的变量,而不是捕获一个已存在的变量。这种方式可以使用 auto 关键字来推导类型,也可以显式指定类型。这种方式可以用来捕获只移动的变量,或者捕获 this 指针的值。

1
2
3
4
5
6
7
int x1 = 10;
int x2 = 10;
int x3 = 0;
auto f = [xsum = x1+x2,x3](int num) -> int {return xsum+x3+num; };
std::cout << f(5) << std::endl; //输出:25
x3 = 40;
std::cout << f(5) << std::endl; //输出:25