Bootstrap

C++之Lambda表达式(匿名函数)

1.定义:C++中创建匿名函数(不带名字的函数)使用Lambda表达式,Lambda表达式允许我们在需要函数对象的地方定义和简短的使用函数,而无需显示定义具体名的函数

定义一个匿名函数一共有三步
①[] 使用匿名函数外部函数定义的变量,例如i变量,但是在匿名函数内部不允许修改,若要强制修改,用引用,需变为[&i]。 若外部的所有变量都想在匿名函数里边仅使用,变为[=]。若想改变值则变为[&]。 [=,&j]表示除了j是引用之外,其它变量是值传递
②() 传入形参,例如(int a ,int b)
③{} 代码编写

1.1 表达式语法:[捕获列表] (参数列表) -> 返回值类型 {函数体}

注:在编写Lambda表达式的时候,可以忽略参数列表和返回值类型,但是捕获列表和函数体必须包含,其中[ ] 不能省略,编译根据它来识别后面是否是Lambda表达式,并且它还有一个作用就是能够让Lambda的函数体访问它所处作用域的成员。

1.2示例

#include <iostream>
using namespace std;
int main() {
	//示例1-加法
	[](int a, int b)->int {
		return a+b ;
		};
	//示例2-如果编译器能够推断出来类型,则->也可以省略
	[](int a, int b) {
		return a+b ;
		};
	//示例3-一个最简单的lambda表达式
	[] () {};
	return 0;
}

1.3 捕获列表的说明

        Lambda表达式需要在函数体中定义,这时如果想访问所处函数中的某个成员,那么就需要使用捕获列表了。捕获列表的写法通常有以下几种形式:

形式作用
[a]表示值传递方式捕获a
[=]表示值传递方式捕获所有父作用域所有变量(包括this)
[&a]表示引用传递方式捕获变量a
[&]表示引用传递方式捕获所有父作用域所有变量(包括this)
[this]表示值传递方式捕获当前的this指针
[=,&a,&b]通过引用方式捕获a和b,值传递方式捕获其它变量

 2.Lambda表达式的使用

        Lambda表达式定义出来并不会自己调用,而是要进行手动调用,调用方式包括两种

  • 使用变量接收,然后再调用
int main() {
    int i = 100;
    int j = 200;
    //使用变量接受然后再调用 
    //定义了一个匿名函数,让c变量保存了这个函数
    auto c = [&i,&j](int a,int b) ->int {   //->int 表示返回值的类型为int型
    i = 1;   //对i和J使用了引用,可以在匿名函数中修改值
    cout << "i=" << i << endl;
    cout << "a="  << a << endl;
    cout << "b=" << b << endl;
     return 45;
    };
    //c变量保存了匿名函数,所以c()就相当于调用了这个函数,67,98是实参
    int ref = c(67,98);
    cout << "i=" << i << endl;
    cout << "ref" << ref << endl;
}

运行结果:

  • 不使用变量接受直接调用,在{}后边添加一个()
int main() {
    //定义了一个匿名函数,不接受表达式直接引用
    int A = [&](int m,int n)->int{
        return m+n;
    }(123,456);  //()调用匿名函数
    cout << "A=" << A << endl;
    cout << "-----------------" << endl;
	return 0;
}

运行结果:

3.Lambda的应用场景

编写Lambda表达式很简单,但是用得上Lambda表达式比较特殊。在C++内部,函数的内部不允许再定义函数,如果函数中需要使用到某一个函数帮助计算并返回结果,代码又不是很多,那么Lambda表达式不失为一种上佳选择。如果没有Lambda表达式,那么必须在函数的外部去定义一个内联函数。来回查看代码比较拖沓,定义Lambda函数,距离近些,编码效率高些,对于计算机来说不用开辟新的内存去存放内联函数。

;