c++的lambda表达式捕获this_匿名函数lambda表达式

2023-05-16

在C++11中引入了匿名函数,也就是所谓的lambda表达式;其实这个表达式在python、JAVA等语言中早就已经存在了,但是很不建议大家使用这个表达式;原因是这种表达式一出现,很多人都是蒙圈的,但是偏偏有很大一部分人喜欢使用,简便;程序员的世界是不懂的,只能随他们去吧!!!

但是,作为一名程序员,自己不写这类惹人蒙圈的东西,但是要能看的懂这类骚操作~~~


一、lambda表达式概述

lambda 表达式是一种匿名函数,即没有函数名的函数;该匿名函数是由数学中的λ演算而来的。通常情况下,lambda函数的语法定义为:

[capture] (parameters) mutable ->return-type {statement}

意义:

[capture] :捕捉列表。捕捉列表总是作为lambda的开始,即出现于lambda的开始处。它是lambda的引出符(即开始标志)。编译器可以根据该“标志”来作出判断出该函数是否为lambda函数。同时“捕捉列表”能够捕捉上下文中的变量以作为lambda函数使用。
(parameters):参数列表。和C/C++中的普通函数参数意义一样。该部分是可选的,意味着如果我们不需要进行参数传递时,可以连同括号“()”一起省略掉。
mutable:该关键字为一个修饰符。在默认的情况下,lambda函数总是返回一个const喊,而当我们在参数列表后面注明了“mutable”关键字之后,则可以取消其常量性质。若在lambda中使用了mutable修饰符,则“参数列表”是不可省略掉的(即使是参数为空)。
->return-type: 函数的返回值类型。和C/C++中的普通函数返回值类型的性质一样。主要目的是用来追踪lambda函数(有返回值情况下)的返回类型。若lambda函数不需要返回值,则可以直接将这部分省略掉。
{statement}:函数体。在该函数体中,除了可以使用参数列表中的变量外,还可以使用所有捕获到的变量(即[capture] 中的变量)。

如图:

对于匿名函数,一般用于传函数参数,当然也可以直接定义调用.

		auto pfun=[]{cout<<"hello world"<<endl;}		//这里使用auto自动判断类型  其实是函数指针
		pfun();						//调用这个函数

二、捕获列表

规则:

[]:什么也不捕获
[=]:捕获所有一切变量,都按值捕获
[&]:捕获所有一切变量,都按引用捕获
[=, &a]:捕获所有一切变量,除了a按引用捕获,其余都按值捕获
[&, =a]:捕获所有一切变量,除了a按值捕获,其余都按引用捕获
[a]:只按值捕获a
[&a]:只按引用捕获a
[a, &b]:按值捕获a,按引用捕获b

1.[=]拷贝捕获

#include <iostream>

using namespace std;

int main()
{
	int i = 1024;
	auto func = [=] {	// [=] 表明将外部的所有变量拷贝一份到该函数内部
		cout << i <<endl;
	};
	auto func2 = [] { //未指名捕获, i 不存在
		cout << i<< endl;
	};
	func();
	return 0;
}

2.[&]引用捕获

#include <iostream>

using namespace std;

int main()
{
	int i = 1024;
	cout << &i << endl;
	auto pfun = [&] {
		cout << &i << endl;
	};
	pfun();
	return 0;
}

3.[=, &] 拷贝与引用混合

#include <iostream>
using namespace std;
 
int main()
{
    int i = 1024, j = 2048;
 
    cout << "i:" << &i << endl;
    cout << "j:" << &j << endl;
 
    auto fun1 = [=, &i]{ // 默认拷贝外部所有变量,但引用变量 i
        cout << "i:" << &i << endl;
        cout << "j:" << &j << endl;
    };
    fun1();
	return 0;
}

结果

outside i:0x28ff0c
outside j:0x28ff08
inside i:0x28ff0c
inside j:0x28ff04

4.[bar] 指定引用或拷贝

#include <iostream>
using namespace std;
 
int main()
{
    int i = 1024, j = 2048;
 
    cout << "outside i value:" << i << " addr:" << &i << endl;
 
    auto fun1 = [i]{
        cout << "inside  i value:" << i << " addr:" << &i << endl;
        // cout << j << endl; // j 未捕获
    };
    fun1();
}

结果:

outside i value:1024 addr:0x28ff08
inside i value:1024 addr:0x28ff04

#include <iostream>
using namespace std;
 
int main()
{
    int i = 1024, j = 2048;
 
    cout << "outside i value:" << i << " addr:" << &i << endl;
 
    auto fun1 = [&i]{
        cout << "inside  i value:" << i << " addr:" << &i << endl;
        // cout << j << endl; // j 未捕获
    };
    fun1();
}

结果:

outside i value:1024 addr:0x28ff08
inside i value:1024 addr:0x28ff08
#include <iostream>
using namespace std;
int main()
{
int i = 1024, j = 2048, k;
cout << "outside i:" << &i << endl;
cout << "outside j:" << &j << endl;
auto fun1 = [i, &j]{
cout << "inside i:" << &i << endl;
cout << "inside j:" << &j << endl;
// cout << k; // k 未捕获
};
fun1();
}

结果:

outside i:0x28ff0c
outside j:0x28ff08
inside i:0x28ff00
inside j:0x28ff08

5.[this] 捕获 this 指针

#include <iostream>
using namespace std;
 
class test
{
public:
    void hello() {
        cout << "test hello!n";
    };
    void lambda() {
        auto fun = [this]{ // 捕获了 this 指针
            this->hello(); // 这里 this 调用的就是 class test 的对象了
        };
        fun();
    }
};
 
int main()
{
    test t;
    t.lambda();
}

三、案例

#include <iostream>

using namespace std;

int main()
{
	int a = 1, b = 2;
	auto lambda = [](int a, int b) {
		b = a + a + a;
		return a + b;
	};
	cout<<lambda(a,b)<<endl;
	auto pFun = [] {
		cout << "hello lambda" << endl;
	};
	pFun();
	return 0;
}

四、lambda 表达式与function

C++11中,新增加了一个std::function对象,std::function对象是对C++中现有的可调用实体的一种类型安全的包裹(我们知道像函数指针这类可调用实体,是类型不安全的);关于function的介绍前面有响应的笔记;

直接看例子比较直接:

#include <iostream>
#include <functional>

using namespace std;

function<void(int)> pfun;

int main()
{
	pfun = [](int x){
		cout << "x:"<<x << endl;
	};
	pfun(3);
	return 0;
}

结果:

x:3

声明function函数,返回值为空,参数为int型;类似函数指针,我们将值传入即可


想了解学习更多C++后台服务器方面的知识,请关注:

微信公众号:C++后台服务器开发

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c++的lambda表达式捕获this_匿名函数lambda表达式 的相关文章

随机推荐