当前位置: 首页 > article >正文

C++ lambda表达式

目录

1.lambda表达式

1.1什么是Lambda表达式?

1.2Lambda表达式的语法

1.3捕捉列表

1.4函数对象与lambda表达式


1.lambda表达式

1.1什么是Lambda表达式?

Lambda表达式是C++11标准引入的一种匿名函数,它允许你在需要函数的地方直接编写代码块,而无需定义一个完整的函数。Lambda表达式通常用于简化回调函数、简化STL算法的使用等场景。

1.2Lambda表达式的语法

[capture_list] (parameters) mutable-> return_type {
    // function body
}

  • capture_list:捕获列表,用于指定Lambda表达式可以访问的外部变量。编译器根据[]来
    判断接下来的代码是否为lambda函数,捕捉列表能够捕捉上下文中的变量供lambda
    函数使用。

  • parameters:参数列表,普通函数的参数列表一致,如果不需要参数传递,则可以
    连同()一起省略

  • mutable:默认情况下,lambda函数总是一个const函数,mutable可以取消其常量
    性。使用该修饰符时,参数列表不可省略(即使参数为空)。

  • return_type:返回值类型。用追踪返回类型形式声明函数的返回值类型,没有返回
    值时此部分可省略。返回值类型明确情况下,也可省略,由编译器对返回类型进行推
    导。

  • function_body:函数体,在该函数体内,除了可以使用其参数外,还可以使用所有捕获
    到的变量。

注意:
在lambda函数定义中,参数列表和返回值类型都是可选部分,而捕捉列表和函数体可以为
空。因此C++11中最简单的lambda函数为:[]{};该lambda函数不能做任何事情。

// lambda 匿名函数的对象
int main()
{
    
	auto add1 = [](int x, int y)->int {return x + y; };
	cout << add1(1, 2) << endl;

	auto func1 = []()->int
	{
		cout << "hello world" << endl;
		return 0;
	};

	func1();

	// 返回值类型可自动推导类型,所以可以省略
	// 无参数可以省略
	auto func2 = []
	{
		cout << "hello world" << endl;
		return 0;
	};

	cout << func2() << endl;

	auto func3 = []
	{
		cout << "hello world" << endl;
	};

	func3();

	return 0;
}

lambda表达式实际上可以理解为无名函数,该函数无法直接调用,如果想要直接调用,可借助auto将其赋值给一个变量。


1.3捕捉列表


    捕捉列表描述了上下文中那些数据可以被lambda使用,以及使用的方式传值还是传引用。

    • [var]:表示值传递方式捕捉变量var
    • [=]:表示值传递方式捕获所有父作用域中的变量(包括this)
    • [&var]:表示引用传递捕捉变量var
    • [&]:表示引用传递捕捉所有父作用域中的变量(包括this)
    • [this]:表示值传递方式捕捉当前的this指针
    int main()
    {
    	// 只能用当前lambda局部域和捕捉的对象和全局对象
    
    	int a = 0, b = 1, c = 2, d = 3;
    	// 所有值传值捕捉
    	auto func1 = [=]
    	{
    		int ret = a + b + c + d; // 都捕捉了都能用
    		return ret;
    	};
    	
    	// 所有值传引用捕捉
    	auto func2 = [&]
    	{
            // 传引用捕捉能修改
    		a++;
    		b++;
    		c++;
    		d++;
    		int ret = a + b + c + d;
    		return ret;
    	};
    
    	// 混合捕捉
    	auto func3 = [&a, b]
    	{
            // a能修改,b不能
    		a++;
    		// b++;
    		int ret = a + b;
    		return ret;
    	};
    
    	// 混合捕捉
    	// 所有值以引用方式捕捉,d用传值捕捉
    	auto func4 = [&, d]
    	{
    		a++;
    		b++;
    		c++;
    		//d++;  // d传值捕捉不能修改,其他传引用捕捉都能修改
    
    		int ret = a + b + c + d;
    	};
    
    	auto func5 = [=, &d]() mutable // 加了mutable取消了const,传值捕捉的a,b,c都能修改
    	{
    		a++;
    		b++;
    		c++;
    		d++;
    		int ret = a + b + c + d;
    	};
    
    	return 0;
    }

    1.4函数对象与lambda表达式

    函数对象(也称为仿函数或functor)是一种重载了函数调用操作符operator()的类。这意味着函数对象可以像普通函数一样被调用。

    // 定义一个简单的函数对象
    class Add {
    public:
        Add(int z)
            :_z(z)
            {}    
    
    	int operator()(int x, int y) const {
    		return x + y + _z;
    	}
    private:
        int _z;
    };
    
    int main()
    {
        int z = 1;
    	// 函数对象
    	Add add(1);
    	cout << add(2, 3) << endl;
    
    	// lambda表达式
    	auto lam = [z](int a, int b)->int
    		{
    			return a + b + z;
    		};
    	cout << lam(2 ,3) << endl;
    
    	return 0;
    }

    从使用方式上来看,函数对象与lambda表达式完全一样。 函数对象将z作为其成员变量,在定义对象时给出初始值即可,lambda表达式通过捕获列表可以直接将该变量捕获到。

    实际在底层编译器对于lambda表达式的处理方式,完全就是按照函数对象的方式处理的,即:如 果定义了一个lambda表达式,编译器会自动生成一个类,在该类中重载了operator()。



    http://www.kler.cn/a/517452.html

    相关文章:

  • Java编程语言:从入门到进阶的全面指南
  • 数仓的数据加工过程-ETL
  • 《探秘鸿蒙Next:非结构化数据处理与模型轻量化的完美适配》
  • 总结8..
  • Qt —— 控件属性(二)
  • C++的new和delete
  • C#集合排序的三种方法(List<T>.Sort、LINQ 的 OrderBy、IComparable<T> 接口)
  • 前端开发常用的设计模式有哪些
  • 机器学习-学习类型
  • Mysql意向锁
  • 深入解析 Linux 内核中的 InfiniBand 驱动接口:ib_verbs.h
  • 二叉树相关oj题 1. 检查两颗树是否相同。
  • 多线程详解——IntentService工作原理(源码详解)
  • PC端实现PDF预览(支持后端返回文件流 || 返回文件URL)
  • 【竞技宝】DOTA2:NAVI junior被ESL取消参赛资格
  • springfox-swagger-ui 3.0.0 配置
  • 无监督学习:聚类、异常检测
  • C++AVL树(二)详解
  • 港科夜闻 | 香港科大获三千万基金资助,开发人工智能英语评估及学习系统,供全港中学生免费使用...
  • PostgreSQL中级专家是什么意思?