C++ lambda表达式

lambdaC++11非常重要特性之一

  • 可以就地匿名定义目标函数函数对象不需要一个函数
  • lambda是一个匿名内联函数调用地方直接展开避免了函数调用开销

[  捕获列表 ]( 参数列表 ) ->  返回值类型 { 函数体 } 
  • 要是没有参数列表可以省略
  • 捕获列表对于函数捕获外围变量权限

捕获列表

  • [ ] 不捕获任何变量
  • & ] 引用捕获外部作用域中的所有变量
  • [ = ] 捕获外部作用域中的所有变量 拷贝来的副本也只是可读的
  • [ =,&a ] 值捕获外部作用域中的所有变量,引用捕获外部变量a
  • ] 值捕获a变量 不捕获其他变量
  • [ this 捕获当前类的this指针,让lambda表达式拥有和当前类成函数同样的访问权限
  • [ *this ] C++17之后可以按值捕获实例
  • k=7 ] C++14可以定义新的对象并且初始 无需外围环境

参数列表

        C++14还支持参数列表使用auto类型,如[](auto a,auto b){return a+b};只要是支持+运算符的都可以适用,类型模板

返回值

        -> 返回值类型一般可以省略编译器根据return语句自动推导返回值类型

        但是注意lambda不能通过列表初始化自动推导返回值类型

lambda函数指针

  • 函数指针定义在别的地方代码阅读不方便
  • 效率,比较于使用内联函数的指针,使用函数指针可能导致编译器不对其进行inline优化比较非内函数调用次数情况lambda避免函数开销提升效率。

代码

class A
{
private:
	int pri;
public:
	void play() {  };
	void fun(int x, int  y)
	{
		auto f1 = [this, x, y]()
			{
				play();
				pri = x;
				return pri + x + y;
			};//成功:捕获类this 获取类成员成员函数相同权限 可读 可修改
	}
};

int main()
{
	int a = 1, b = 2;
	auto f1 = []() {return a; }; //错误:未捕获a 无法访问a
	auto f2 = [&a]() { a++; }; //成功:引用捕获a 可以直接对a操作
	auto f3 = [a]() {a++; }; //错误:值捕获a 副本也是可读不可改
	auto f4 = [=](int c) {= a; return a; };//成功:值捕获全局 返回int类型
	auto f5 = [&] {a++; int c = a; b = c; }; //成功:引用捕获全局 参数列表可以省略 

//值捕获a 引用捕获b的几种方式
	auto f6 = [a, &b] {}; 
	auto f6 = [=, &b] {};
	auto f6 = [&, a] {};

//返回值一般可忽略
	//错误: 但是不能是列表初始化 无法给自动lambda提供返回值
	auto f7 = [](){return { 1,2,3 }; }; 
	//正确:显示声明函数的返回值
	auto f7 = []()->vector<int>{return { 1,2,3 }; };
}


vector<int>vec{ 7,9,4,1,6,2 };

//实例使用:利用lambda改变sort的排序顺序
void text1() {
	auto f = [](int a, int b) {
		return a > b;
		};
	sort(vec.begin(), vec.end(), f);
	//也可以直接用lambda表达式——返回闭包对象:匿名函数
	sort(vec.begin(), vec.end(), [](int a, int b) {
		return a > b;
		}
	);
}

//内联函数指针和lambda
inline void func(int i)//内联函数
{
	if (>= 5)
		vec.push_back(i);
}
void text2() {
	//传统迭代器for循环 
	for (auto itr = vec.begin(); itr != vec.end(); ++itr)
	{
		if (*itr >= 5)
			vec.push_back(*itr);
	}
	//使用内联函数指针和for_each
	for_each(vec.begin(), vec.end(),func);
	//使用lambda和for_each
	for_each(vec.begin(), vec.end(), [=](int i) {
			if (>= 5)
				vec.push_back(i);
		}
	);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值