C++ 与Lambda表达式
  xeLzCLQsmmZ4 2023年11月02日 23 0

1 Lambda函数简介

Lambda来自lambda calculus(lambda演算),一种定义和应用函数的数学系统。这个系统中可以使用匿名函数,对于接收函数指针或伪函数的函数,可以使用匿名函数定义(lambda)作为其参数。


1.1 为什么使用lambda函数?

距离:定义位于使用的地方附近很有用,由于函数不能定义在函数中,编译器传统意义上也不会内联其他地址被获取的函数,因为函数地址的概念意味着非内联函数,伪函数也可以定义在使用附近,因此,lambda和伪函数比函数近


简洁:伪函数代码比函数和lambda繁琐


1.2 引入lambda的目的

让程序员能够将类似于函数的表达式用作接收函数指针或伪函数的函数的参数。典型的lambda是测试表达式和比较表达式,可编写一条返回语句。这使得lambda简洁易于理解,且可自动推断返回类型。


2 lambda函数的使用

2.1 简单使用

//lambda返回类型相当于使用decltyp根据返回值推断得到;如果lambda不包含返回语句,推断出的返回类型将为void。
[](int x) {return x % 3 == 0;}
//使用整个lambda表达式替换函数指针或伪函数构造函数
count3 = std::count_if(numbers.begin(), numbers.end(),[](int x){return x % 3 == 0;});

2.2 返回类型后置lambda

//仅当lambda表达式完全由一条返回语句组成时,自动类型推断才管用,否则,需要使用新增的返回类型后置语法
[](double x)->double{int y = x; return x – y;} // return type is double

2.3 有名字的lambda函数

auto mod3 = [](int x){return x % 3 == 0;} // mod3 a name for the lambda
//可以像使用函数一样使用带有名字的lambda函数
bool result = mod3(z); // result is true if z % 3 == 0

2.4 可访问作用域内任何变量的lambda

//[z]---按值访问变量
//[&count]---按引用访问变量
//[&]---按引用访问所有动态变量
//[=]---按值访问所有动态变量
//[&,ted]---按值访问ted,按引用访问其他动态变量
//其他混合方式也允许
int count13 = 0;
std::for_each(numbers.begin(), numbers.end(),
[&count13](int x){count13 += x % 13 == 0;});//此时count13就可以记录可以整除13的x的数量

3 测试程序

3.1 代码

/*
Project name :			_33lambda_func
Last modified Date:		2022年5月5日21点04分
Last Version:			V1.0
Descriptions:			C++ 的 lambda用法
*/
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <ctime>
const long Size1 = 39L;
const long Size2 = 10 * Size1;
const long Size3 = 10 * Size2;
const long Size4 = 10 * Size3;
bool f3(int x) { return x % 3 == 0; }
bool f13(int x) { return x % 13 == 0; }
int main()
{
	using std::cout;
	using std::endl;
	std::vector<int> numbers(Size1);
	std::srand(std::time(0));
	std::generate(numbers.begin(), numbers.end(), std::rand);
	// using function pointers
	cout << "使用函数指针*********************************************************" << endl;
	cout << "Sample size = " << Size1 << '\n';
	long count3 = std::count_if(numbers.begin(), numbers.end(), f3);
	cout << "Count of numbers divisible by 3: " << count3 << '\n';
	long count13 = std::count_if(numbers.begin(), numbers.end(), f13);
	cout << "Count of numbers divisible by 13: " << count13 << "\n\n";

	// increase number of numbers
	numbers.resize(Size2);
	std::generate(numbers.begin(), numbers.end(), std::rand);
	cout << "使用伪函数***********************************************************" << endl;
	cout << "Sample size = " << Size2 << '\n';
	// using a functor
	class f_mod
	{
	private:
		int dv;
	public:
		f_mod(int d = 1) : dv(d) {}
		bool operator()(int x) { return x % dv == 0; }
	};
	count3 = std::count_if(numbers.begin(), numbers.end(), f_mod(3));
	cout << "Count of numbers divisible by 3: " << count3 << '\n';
	count13 = std::count_if(numbers.begin(), numbers.end(), f_mod(13));
	cout << "Count of numbers divisible by 13: " << count13 << "\n\n";

	// increase number of numbers again
	numbers.resize(Size3);
	std::generate(numbers.begin(), numbers.end(), std::rand);
	cout << "lambda函数简单使用**************************************************" << endl;
	cout << "Sample size = " << Size3 << '\n';
	// using lambdas
	count3 = std::count_if(numbers.begin(), numbers.end(),
		[](int x) {return x % 3 == 0; });
	cout << "Count of numbers divisible by 3: " << count3 << '\n';
	count13 = std::count_if(numbers.begin(), numbers.end(),
		[](int x) {return x % 13 == 0; });
	cout << "Count of numbers divisible by 13: " << count13 << "\n\n";

	// increase number of numbers again
	numbers.resize(Size4);
	std::generate(numbers.begin(), numbers.end(), std::rand);
	std::generate(numbers.begin(), numbers.end(), std::rand);
	cout << "Sample size = " << Size4 << '\n';
	// using lambdas
	count3 = std::count_if(numbers.begin(), numbers.end(),
		[](int x) {return x % 3 == 0; });
	cout << "Count of numbers divisible by 3: " << count3 << '\n';
    count13 = 0;
	std::for_each(numbers.begin(), numbers.end(),
		[&count13](int x) {count13 += x % 13 == 0; });
	cout << "Count of numbers divisible by 13: " << count13 << "\n\n";
	// using a single lambda
	cout << "可访问作用域内任何变量的lambda***************************************" << endl;
	count3 = count13 = 0;
	cout << "Sample size = " << Size4 << '\n';
	std::for_each(numbers.begin(), numbers.end(),
		[&](int x) {count3 += x % 3 == 0; count13 += x % 13 == 0; });
	cout << "Count of numbers divisible by 3: " << count3 << '\n';
	cout << "Count of numbers divisible by 13: " << count13 << "\n\n";
	cout << "返回类型后置lambda and 有名字的lambda函数****************************" << endl;
	auto mod3 = [](double x)->double {int y = x; return x - y; };// return type is double
	double result = mod3(9.99);
	cout << "result = " << result << endl;
	return 0;
}

3.2 运行结果

使用函数指针*********************************************************
Sample size = 39
Count of numbers divisible by 3: 13
Count of numbers divisible by 13: 1

使用伪函数***********************************************************
Sample size = 390
Count of numbers divisible by 3: 138
Count of numbers divisible by 13: 23

lambda函数简单使用**************************************************
Sample size = 3900
Count of numbers divisible by 3: 1339
Count of numbers divisible by 13: 306

Sample size = 39000
Count of numbers divisible by 3: 13065
Count of numbers divisible by 13: 2949

可访问作用域内任何变量的lambda***************************************
Sample size = 39000
Count of numbers divisible by 3: 13065
Count of numbers divisible by 13: 2949

返回类型后置lambda and 有名字的lambda函数****************************
result = 0.99

D:\Prj\_C++Self\_33lambda_func\x64\Debug\_33lambda_func.exe (进程 2692)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

xeLzCLQsmmZ4