C++11中Lambda表达式之捕获

捕获是指一个lambda表达式将局部变量包含在捕获列表,在捕获列表中的参数则可以被lambda函数体使用。举一个最简单的例子:

std::string str("this is captured value");
auto f = [str] {std::cout << str << std::endl;};

在例子中我们可以看出,通过捕获局部变量,lambda表达式可以在函数体重使用该变量,和参数传递的效果一样。但在某些场合中,lambda捕获则表现出巨大的作用,比如当lambda表达式作为谓词使用在STL的算法函数中的时候。比如实现一个函数,将一个vector < int >中的大于某一个数的修改为0。

#include <algorithm>    // std::transform
#include <iostream>

std::vector<int>& modifyVector(std::vector<int>& data,int upperBound)
{
	auto modifyFunc= [upperBound](int item) ->int { return (item >= upperBound) ? 0:item; };
	std::transform(data.begin(), data.end(), data.begin(), modifyFunc);
	return data;
}

void printVector(const std::vector<int>& data)
{
	for(auto item = data.cbegin();item != data.cend();item++)
	{
		std::cout << *item << " ";
	}
	std::cout << std::endl;
}

int main()
{
	std::vector<int> data{ 6,4,3,4,5,7,8,7,6,6,5 };
	std::cout << "original data: ";
	printVector(data);
	
	modifyVector(data, 7);
	std::cout << "modified data: ";
	printVector(data);
	return 0;
}

运行结果如下:

运行结果

lambda捕获有两种捕获方式,分别是值捕获和引用捕获。
值捕获就像前面例子那样,与传值参数类似,采用值捕获的前提是变量可以拷贝复制,与参数不同,被捕获的变量的值是在lambda创建时拷贝,而不是调用时拷贝,比如:

int a = 30;
auto f = [a] {return a;};
a = 0;
auto b = f();  //b = 30

由于被捕获的变量的值是在lambda创建时复制的,所以随后对其的修改并不会影响到lambda内对应的值。
lambda也可以采用引用捕获变量,其工作方式和引用相同。例如:

int a = 30;
auto f = [&a] {return a;};
a = 0;
auto b = f();  //b = 0

引用捕获和返回引用有相同的问题和限制,如果我们采用引用方式捕获一个变量,就必须确保被引用对象在lambda执行时时存在的。所以一般建议保持lambda变量捕获简单化,对于普通变量,如int,float和string等类型,通常采用值捕获。对于捕获指正,迭代器或采用引用捕获,就必须要保证其在lambda执行时,迭代器、指正和引用的对象依然存在,且有预期值。
以上捕获为显示捕获,除了显示列出我们希望使用的变量外,还可以使用隐式捕获,即让编译器自己来推断我们需要捕获什么变量。我们在捕获列表中使用=或&,=表示采用值捕获,&表示引用捕获。例如:

int func(int v1, int v2)
{
	auto func = [=] {return v1+v2;};
	return func();
}

int func2(int& v1,int& v2)
{
    auto f = [&] {return v1+v2;};
    return f();
}

int main()
{
	auto v = func(2,3); //v = 5
	
	int a1 = 3;
	int a2 = 4;
	v = func2(a1,a2); //v = 7
	
	return 0;
}
  • 11
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值