C++11/14学习(八)Lambda表达式

Lambda 表达式是 C++11 中最重要的新特性之一。类似匿名函数,当需要一个函数但是又不想费力去命名时使用。
这样的场景其实有很多,所以匿名函数几乎是现代编程语言的标配。

Lambda 表达式基础

Lambda 表达式的基本语法如下:

[捕获列表](参数列表) mutable(可选)异常属性 -> 返回类型 {
	// 函数体
}

捕获列表,可以理解为参数的一种类型。
lambda 表达式内部函数体在默认情况下是不能够使用函数体外部的变量的,这时候捕获列表可以起到传递外部数据的作用。
根据传递的行为,捕获列表也分为以下几种:

  1. 值捕获
    值捕获的前提是变量可以拷贝,被捕获的变量在 lambda 表达式被创建时拷贝,而非调用时才拷贝:
void learn_lambda_func_1() {
	int value_1 = 1;
	auto copy_value_1 = [value_1] {
		return value_1;
	};
	value_1 = 100;
	auto stored_value_1 = copy_value_1();
	// 这时, stored_value_1 == 1, 而 value_1 == 100.
	// 因为 copy_value_1 在创建时就保存了一份 value_1 的拷贝
}
  1. 引用捕获
    引用捕获保存的是引用,值会发生变化:
void learn_lambda_func_2() {
	int value_2 = 1;
	auto copy_value_2 = [&value_2] {
		return value_2;
	};
	value_2 = 100;
	auto stored_value_2 = copy_value_2();
	// 这时, stored_value_2 == 100, value_1 == 100.
	// 因为 copy_value_2 保存的是引用
}
  1. 隐式捕获
    手动书写捕获列表有时候是非常复杂的,这种机械性的工作可以交给编译器来处理。
    可以在捕获列表中写一个 & 或 = 向编译器声明采用 引用捕获或者值捕获。
    捕获列表的最常用的四种形式可以是:
  • [] 空捕获列表
  • [name1, name2, …] 捕获一系列变量
  • [&] 引用捕获, 让编译器自行推导捕获列表
  • [=] 值捕获, 让编译器执行推导应用列表
  1. 表达式捕获(C++14)
    这部分内容需要了解后面马上要提到的右值引用以及智能指针
    上面提到的值捕获、引用捕获都是已经在外层作用域声明的变量,因此这些捕获方式捕获的均为左值,而不能捕获右值。
    C++14允许捕获的成员用任意的表达式进行初始化。
    被声明的捕获变量类型会根据表达式进行判断,判断方式与使用auto 本质上是相同的:
#include <iostream>
#include <utility>
int main() {
	auto important = std::make_unique<int>(1);
	auto add = [v1 = 1, v2 = std::move(important)](int x, int y)
		-> int {
		return x + y + v1 + (*v2);
	};
	std::cout << add(3, 4) << std::endl;
	return 0;
}

在上面的代码中, important 是一个独占指针,是不能够被捕获到的,这时候我们需要将其转移为右值,在表达式中初始化。

泛型 Lambda(C++14)

Lambda 表达式并不是普通函数,所以 Lambda 表达式并不能够模板化。
这就为我们造成了一定程度上的麻烦:参数表不能够泛化,必须明确参数表类型。
从 C++14 开始,Lambda 函数的形式参数可以使用 auto 关键字来产生意义上的泛型:

auto add = [](auto x, auto y) {
	return x + y;
};
add(1, 2);
add(1.1, 2.2);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值