C++11 Lambda 表达式

1. Lamda 表达式介绍

lambda表达式:也就是匿名函数,也可以称作闭包(Closure),字面意义是没有名字的函数。它可以很方便地让我们随手定义函数,并把函数当做参数,给其他函数调用。这样的代码写起来很简洁,读起来也直观。

举例1:对序列 {0,11,3,19,22,7,1,5} 如何从小到大排序呢?,可以通过定义匿名函数的方式实现。

#include 
#include 
#include 

using namespace std;

int main()
{
	vector <int> vec {0,11,3,19,22,7,1,5};
	auto f =[](int a, int b)
	{
		return  a<b;  // ab从大到小排序
	};
	sort(vec.begin(),vec.end(),f);
}
  • sort第3个参数,传入的就是匿名函数,这样的写法相比原始的c++要灵活简洁很多。

2 Lambda表达式语法

C++11 Lambda 表达式_第1张图片

  • 首先需要写一个方括号[ ], 里面可以传入捕获变量的形式或者为空
  • 然后是()包起来的参数列表
  • 然后是 -> 并跟着返回值类型
  • 最后是函数的实现主体body

举例2:

auto f = [](int a, int b) ->int {
	return a+b;
};
cout << f(1,2) <<endl;
>> 3
  • 方括号[ ]里面是空的,表示不捕获外围的变量
  • 这里lambda的返回值int 是可以忽略的,因为编译器可通过return a+b以及参数类型,自行推断它的返回类型。所以可以等价于如下:
auto f = [](int a, int b){
	return a+b;
};
cout << f(1,2) <<endl;

2.1 变量捕获(Capture Cluse)

  • 变量捕获就是方括号部分,作用是让我们匿名函数可以访问,甚至修改函数外部的变量,
  • [ ]中可以指定一些外围的变量,这样在匿名函数内部就可以访问这些变量。如果是空的[]表示不捕获任何变量。
  • 如果变量名前面有引用符号&,表示按引用捕获,可以修改外部变量的值。如果不加引用符号&,就表示按值捕获,不能修改外围变量的值

举例3:

int N =100, M =10;

auto g = [N,&M](int i)
{
	M=20;
	return N*i;
}

cout << g(10) << endl;
cout << M << endl;

输出

>> 1000   // 100*10
>> 20     // 匿名函数内部M赋值为20

注:这里N是没有加&号,只能访问,不能修改。如果尝试给N赋值编译器会报错

[&]

按引用捕获:如果捕获的语句只有引用符号:[&] ,表示所有的变量都按引用捕获,即可以修改外围变量的值。

[=]

按值捕获: 如果捕获语句为[=], 表示所有变量都按值捕获。

[&,=N]

可以单独指定一些变量按值捕获,其他变量都按引用捕获。[&,=N],这种写法表示按值捕获变量N,其他变量按引用捕获。

[this]

可以用this捕获当前实例的指针,在c++17之后,还可以用 [*this] 按值捕获该实例。

2.2 其他特性(c++14后)

支持在捕获语句中定义新变量

在c++14之后,可以在捕获语句中定义新的变量,并且初始化,这些变量无需出现在匿名函数外围环境中

void foo()
{
	int N=100,M=10;
	auto g = [N,&M,K=5](int i)
	{
		M = 20;
		cout << K << endl;
		return N*i;
	};
	
	cout <<g(10) << endl;
	cout << M << endl;
}

在匿名函数中,引入了一个新的变量K,并且给它赋值5,然后再函数主体中打印它

参数类别支持auto类型
[](auto a, auto b) {return a+b;}
在c++14新增的功能,参数列表支持auto类型,这让匿名函数变得更通用,这样只要支出加号类型的变量都可以利用该匿名函数。

你可能感兴趣的:(C++,c++,算法,c语言)