您当前的位置: 首页 >  c++

龚建波

暂无认证

  • 3浏览

    0关注

    313博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

C++ Lambda表达式的基本使用

龚建波 发布时间:2020-03-27 00:42:03 ,浏览量:3

0.前言

Lambda表达式(也叫lambda函数,或简称lambda),是从C++ 11开始引入并不断完善的,是能够捕获作用域中变量的匿名函数对象。因为C++是不能嵌套定义函数的,所以lambda就成了我们构造闭包的主要手段,不过在对象的生命周期上还是有点不同。本文主要展示lambda的基本使用(一些我不常用或者新标准如C++20就先不做笔记了,以在线文档为准)。

目录

1.认识 Lambda

1.1.捕获列表 [ ]

1.2.形参列表 ( ) 

1.3.说明符 

1.4.返回类型 ->

1.5.函数体 { }

2.基本使用

3.参考

1.认识 Lambda

lambda的基本语法如下:

当定义一个lambda时,编译器生成一个与lambda对应的新的(未命名的)类类型。下面对重要的组成部分进行说明:

1.1.捕获列表 [ ]

捕获列表是零或多个捕获符的逗号分隔符列表,可选地以默认捕获符开始(仅有的默认捕获符是 & 和 = )。默认情况下,从lambda生成的类都包含一个对应该lambda所捕获变量的数据成员。类似任何普通类地数据成员,lambda的数据成员也在lambda对象创建时被初始化。类似参数传递,变量的捕获方式也可以是值或引用。

值捕获:

void func()
{
	int i = 100;//局部变量
	//将i拷贝到明位f的可调用对象
	auto f = [i] { return i; };
	i = 0;
	int j = f(); //j=100,因为i是创建时拷贝的
}

引用捕获:

void func()
{
	int i = 100;//局部变量
	//对象f包含i的引用
	auto f = [&i] { return i; };
	i = 0;
	int j = f(); //j=0,传递的是引用
}

除了自己列出捕获列表的变量,还可以让编译器根据lambda中代码来推断我们要使用哪些变量(隐式捕获),用过使用&或=指示编译器推断捕获列表。&则采用引用捕获的方式,=则采用值捕获的方式。混合使用隐式捕获和显示捕获,则两者须使用不同的方式,一个为引用捕获,一个为值捕获。

lambda捕获列表:

  • [ ]。空捕获列表,lambda不能使用所在函数中的变量。
  • [=]。函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是值传递方式(相当于编译器自动为我们按值传递了所有局部变量)。
  • [&]。函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是引用传递方式(相当于编译器自动为我们按引用传递了所有局部变量)。
  • [this]。函数体内可以使用Lambda所在类中的成员变量。
  • [a]。将a按值进行传递。按值进行传递时,函数体内不能修改传递进来的a的拷贝,因为默认情况下函数是const的。要修改传递进来的a的拷贝,可以添加mutable修饰符。
  • [&a]。将a按引用进行传递。
  • [=,&a, &b]。除a和b按引用进行传递外,其他参数都按值进行传递。
  • [&, a, b]。除a和b按值进行传递外,其他参数都按引用进行传递。

悬垂引用:

若以引用隐式或显式捕获非引用实体,而在该实体的生存期结束之后调用lambda对象的函数调用运算符,则发生未定义行为。C++ 的闭包并不延长被捕获的引用的生存期。这同样适用于被捕获的this指针所指向的对象的生存期。

1.2.形参列表 ( ) 

lambda形参列表和一般的函数形参列表类似,但不允许默认实参(C++14 前)。当以 auto 为形参类型时,该 lambda 为泛型 lambda(C++14 起)。与一个普通函数调用类似,调用一个lambda时给定的实参被用来初始化lambda的形参。

//代码在VS2019中测试
void func()
{
	int i = 1, j = 2;
	auto f = [](int a,int &b) {
		a = 10;
		b = 20;
		//输出:10  20
		std::cout             
关注
打赏
1655829268
查看更多评论
0.2259s