C++ lambda表达式【学习笔记】

C++ lambda表达式

lambda表达式组成

  • [捕获列表](参数列表)->返回类型{函数体}
  • 参数列表返回类型可以省略,但捕获列表函数体必须包含;
  • 捕获列表通常为空,返回类型必须使用尾置返回
  • 例:
auto f = []{return 42;};

捕获列表

  • 只用于局部非static变量
  • 值捕获:捕获的变量值是在lambda表达式创建时变量的拷贝,而不是调用时的拷贝
void fcn1(){
	int v1=42;
	auto f=[v1]{return v1;};
	v1=0;
	auto j=f();      //j=42
}
  • 引用捕获:捕获的是变量的引用,而不是拷贝。
void fcn2(){
	int v1=42;
	auto f=[&v1]{return v1;};
	v1=0;
	auto j=f();      //j=0
}

隐式捕获

  • 使得编译器自己推断捕获列表,我们可以告诉编译器使用值捕获还是引用捕获:
  • [=]采用值捕获;
  • [&]采用引用捕获;

显式捕获隐式捕获混用

  • 捕获列表的第一个元素必须是=或者&
  • 显式捕获必须使用和隐式捕获不同的方式:
  • [=, var]:var必须为引用捕获
  • [&,var]:var必须为值捕获

可变lambda

  • 值捕获的lambda表达式中,如果想要改变该变量的值,必须加上关键字mutable
void fcn3(){
	int v1=42;
	auto f=[v1]() mutable {return ++v1;};
	v1=0;
	auto j=f();//j=43
}
  • 在引用捕获中,能否改变捕获变量的值取决于该变量是否是const:
void fcn4(){
	int v1=42;
	auto f=[&v1](){return ++v1;};
	v1=0;
	auto j=f();//j=1
}

捕获列表的作用:

当可调用对象只能接受一个参数,但是需要两个或者多个参数才能完成操作时,这个时候lambda表达式的参数列表只能有一个,哪另外一个参数怎么传进来呢?就是靠捕获列表;

如果要使用函数来替代lambda表达式的功能,碰到这种只能传入单一参数的情况,还有一种解决方式,使用标准库bind函数。

bind函数 (functional头文件)

  • 先定义一个可以传入两个或多个参数完成操作的函数
bool func1(int a1,int a2){
	return a1>=a2;
}
  • 然后使用bind函数将这个func1函数再封装一层:
auto func2=bind(func1,_1,6);
  • 其中_1 _2…是占位符,代表func2的第一个、第二个…参数,我们这里我们将func1的第二个参数绑定为6,这样,func2就变成了一个只需要传入一个参数的函数(可调用对象);func2传入的参数类型和返回类型和func1完全一样。
  • 使用占位符需要使用std::placeholders命名空间:
using namespace std::placeholders;

使用bind可以重排参数顺序

  • 函数g只需要传入两个参数,g(m,n),则mn会分别传入_1_2的位置:
auto g=bind(f,a,b,_2,c,_1);

g(m,n)等价于f(a,b,n,c,m)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章