【面试题】【C++】请你说说 Lambda表达式用法及实现原理?

// 时间:2023年4月20日时间
// 知识点:Lambda 表达式
请你说说,Lambda表达式用法及实现原理?
1. 什么是 Lambda表达式?

   lambda 本质上就是一个简单的,不需要函数名的函数。

2. Lambda 的基本格式是什么?

   其基本格式为:

[捕获参数](函数参数){函数体};

eg:

auto fun = [](){ std::cout << "Hello Lambda" << std::endl; };
3. Lambda 表达式能不能赋值给变量,如果可以,赋值后如何调用?

   可以赋值,Lambda 表达式的返回值是一个函数指针,赋值后该变量可以当作函数指针来调用。

int main(void) {
  auto fun = [](){ cout << "Hello World!" << endl; };
  fun();
  return 0;
}

即便是不赋值,Lambda表达式依旧可以当作一个函数来调用。

int main(void) {
  // Function point
  [](){ cout << "Hello World!" << endl; };
  // Call function
  [](){ cout << "Hello World!" << endl; }();
  return 0;
}

后面不加 () 的 Lambda 表达式相当于函数指针,加上 () 就相当于调用这个 Lambda 函数。

4. Lambda表达式可不可以传递参数?

   可以
eg:

int main(void) {
	int num = 100;
	// 为 Lambda 定义一个 int 类型的参数
	auto fun = [](int num) { num = 5; cout << num << endl; };

	fun(num);
	cout << num << endl; //the output is 100
	return 0;
}

   Lambda 表达式的参数列表就是调用时传递的参数。第二次调用后输出的数值是 100

5. Lambda 表达式捕获参数是什么意思?如何用?

   所谓捕获参数,就是调用之前的变量的意思。
   Lambda 表达式的 [] 用来确定捕获参数:
   1. [=] : 捕获的局部变量只可读不可写,捕获范围是当前 Lambda 表达式之前的作用域。
   2. [&] : 捕获的局部变量可读可写。
eg:

int main(void) {
	int num = 100;

	// read only 
	auto fun1 = [=]() { cout << num << endl; };
	//auto fun1 = [=]() { num = 50;  cout << num << endl; }; // 会报错,编译就不过。
	fun1();

	// read and write
	auto fun2 = [&num]() { num = 200; cout << num << endl; };
	fun2();

	cout << num << endl;// the output is 200
	return 0;
}

   如果用 [=] 再对调用的变量进行修改,会报错,编译就不过。

6. Lambda表达式可以用在类中吗?如果可以,如何捕获 this ?

   可以用在类中,使用 [this] 来捕获 this(感觉像废话一样,但是就是这样。),使用 [&] 捕获所有父作用域的引用,包括 this

void MyClass::function() {
  // 使用 [this] 来捕获 this
  auto fun1 = [this](int v){cout << v + this->num << endl; };
  // 使用 [&] 捕获所有父作用域的引用,包括 this
  auto fun2 = [&](int v){cout << v + this->num << endl; };
}
7. 例子:
int main() {
	vector<int> vec = { 1, 2, 3, 4, 5 };
	// 定义 Lambda
	auto fun = [](int num) { cout << num << endl; };
	//std::for_each(vec.begin(), vec.end(), fun);

	// 将 vec 中的元素都加 1,修改参数必须传递参数的引用
	for_each(vec.begin(), vec.end(), [](int& num) { num += 1; });

	for_each(vec.begin(), vec.end(), fun); // the output is 2 3 4 5 6
	return 0;
}
注:

   1. Lambda 是 const 函数
   Lambda 默认是 const 函数,不能修改引用的变量,使用 mutable 可以取消该属性,但是 mutable 修改的只是副本。
eg:

int main(void) {
  int num = 100;

  // Lamnda is const function, use `mutable` can cancel const
  //auto fun = [=](){ num = 200; cout << num << endl; };
  auto fun = [=]() mutable { num = 200; cout << num << endl; };
  fun();
  // num = 100
  cout << num << endl;
  return 0;
}

   2. Lambda 没有地址
   Lambda 表达式是内联展开的,没有实际的地址,这是与普通函数的一个很大的区别。

int main(void)
{
	string str;
	auto fun = [](string str) {cout << str << endl; };
	cin >> str;
	fun(str);

	//lambda表达式没有地址,是内联展开的
	//cout << (void*)fun << endl; // 会出错,编译不过。
	return 0;
}

   想要输出函数的地址,会报错,编译不过。

参考文献:

   https://www.jianshu.com/p/a200a2dab960

免责声明:

   本文素材来源网络,版权归原作者所有。如涉及作品版权问题,请与我联系删除。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值