草庐IT

lambda表达式基础

yxdong 2023-03-28 原文

1.Lambda的语法

所谓lambda是一份功能定义式,可以被定义于语句(statement)或表达式(expression)内部,因此可以将lambda当作inline函数使用。[]叫做introducer,可以在内部指明一个所谓的capture,用来在lambda内部访问nonstatic外部对象

  • 最简单的lambda
int main()
{
	//定义一个lambda,但没有进行调用
	[] {
		std::cout << "hello lambda!" << endl;
	};

	//定义一个lambda并进行调用
	[] {
		std::cout << "hello lambda1!" << endl;
	}();

	//或者将它传给一个对象
	auto l = [] {
		std::cout << "hello lambda1!" << endl;
	};

	l(); //调用
	cout << sizeof(l) << endl; //answer = 1

	return 0;
}

在lambda introducer和lambda body之间,可以指明参数或mutable,或一份异常明细或attribute specifier以及返回类型。这些是可有可无的,如果出现了,参数所需的小括号就必须出现

lambda语法
1.[...] {...}

2.[...] (...) mutable throwSpec ->retType {...}

lambda可以拥有参数,指明在小括号内
auto l = [] (const string& s) {
    cout << s << endl;
};
l("hello");  

lambda不可以是template,必须始终指明所有类型。

lambda也可以返回某物,但不需要指明返回类型,该类型会根据返回值被推导出来。

int main()
{
	// 1.lambda可以返回某物,不用指明类型,可以自动推导
	auto l = [] {
		return 123;
	};
	int ans = l();
	cout << ans << endl;

	// 2.也可以指明一个返回类型
	auto l2 = []() -> double { //注意()
		return 123;
	};
	double ans2 = l2();
	cout << ans2 << endl;


	return 0;
}

2.Capture(用以访问外部作用域)

在lambda最开始的方括号内,可以指明一个capture用来处理外部作用域内未被传递为实参的数据:

  • [=]意味着外部作用域以by value方式传递给lambda,因此当这个lambda被定义时,你可以读取所有可读数据,但不能修改
  • [&]意味着外部作用域以by reference方式传递给lambda,可以对所有数据进行修改。
  • 也可以个别指明为by value或者by reference,混合使用。也可以[=, &y]取代[x, &y],意思是y以by reference传递,其他实参以by value传递。
int main()
{
	int x = 0;
	int y = 42;
	auto l = [x, &y] {
		// x以by value形式传递, y以by reference方式传递
		cout << "x: " << x << endl; //0
		cout << "y: " << y << endl; //42
		//x++; //error
		y++; //ok
	};
	l();
	cout << "final y: " << y << endl; //43

	return 0;
}

为了得到passing by reference和value的混合体,可以声明lambda为mutable。意思是以by value传递,但是可以在lambda中修改传入的值。

int main()
{
	int x = 0;
	int y = 42;
	auto l = [x, &y]() mutable {
		// x以by value形式传递, y以by reference方式传递
		cout << "x: " << x << endl; //0
		cout << "y: " << y << endl; //42
		x++; //ok
		y++; //ok
	};
	l();
	cout << "final x: " << x << endl; //0
	cout << "final y: " << y << endl; //43

	return 0;
}

3.Lambda的类型

lambda的类型,是一个不具名的function object(或者说functor)。每个lambda表达式的类型是独一无二的。因此如果想根据该类型声明对象,可以借助template或者auto,如果实在需要写下这个类型,可以借助decltype().例如将lambda作为hash function或ordering准则或sorting准则传给容器。

也可以使用C++STL提供的function<>class template指明一个一般化类型给functional programming使用。这个class template提供了"明确指出函数的返回类型为lambda"的唯一办法。

#include <iostream>
#include <functional>
using namespace std;

function<int(int, int)> returnLambda() {
	return [](int x, int y) {
		return x * y;
	};
}

int main()
{
	auto lf = returnLambda();
	cout << lf(5, 7) << endl;
	return 0;
}

有关lambda表达式基础的更多相关文章

  1. ruby 正则表达式 - 如何替换字符串中匹配项的第 n 个实例 - 2

    在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg

  2. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  3. 软件测试基础 - 2

    Ⅰ软件测试基础一、软件测试基础理论1、软件测试的必要性所有的产品或者服务上线都需要测试2、测试的发展过程3、什么是软件测试找bug,发现缺陷4、测试的定义使用人工或自动的手段来运行或者测试某个系统的过程。目的在于检测它是否满足规定的需求。弄清预期结果和实际结果的差别。5、测试的目的以最小的人力、物力和时间找出软件中潜在的错误和缺陷6、测试的原则28原则:20%的主要功能要重点测(eg:支付宝的支付功能,其他功能都是次要的)80%的错误存在于20%的代码中7、测试标准8、测试的基本要求功能测试性能测试安全性测试兼容性测试易用性测试外观界面测试可靠性测试二、质量模型衡量一个优秀软件的维度①功能性功

  4. ruby - 正则表达式将非英文字母匹配为非单词字符 - 2

    @raw_array[i]=~/[\W]/非常简单的正则表达式。当我用一些非拉丁字母(具体来说是俄语)尝试时,条件是错误的。我能用它做什么? 最佳答案 @raw_array[i]=~/[\p{L}]/使用西里尔字符进行测试。引用:http://www.regular-expressions.info/unicode.html#prop 关于ruby-正则表达式将非英文字母匹配为非单词字符,我们在StackOverflow上找到一个类似的问题: https://

  5. ES基础入门 - 2

    ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear

  6. ruby - 正则表达式在哪个位置失败? - 2

    我需要一个非常简单的字符串验证器来显示第一个符号与所需格式不对应的位置。我想使用正则表达式,但在这种情况下,我必须找到与表达式相对应的字符串停止的位置,但我找不到可以做到这一点的方法。(这一定是一种相当简单的方法……也许没有?)例如,如果我有正则表达式:/^Q+E+R+$/带字符串:"QQQQEEE2ER"期望的结果应该是7 最佳答案 一个想法:你可以做的是标记你的模式并用可选的嵌套捕获组编写它:^(Q+(E+(R+($)?)?)?)?然后你只需要计算你获得的捕获组的数量就可以知道正则表达式引擎在模式中停止的位置,你可以确定匹配结束

  7. ruby - 有没有办法从 ruby​​ case 语句中访问表达式? - 2

    我想从then子句中访问c​​ase语句表达式,即food="cheese"casefoodwhen"dip"then"carrotsticks"when"cheese"then"#{expr}crackers"else"mayo"end在这种情况下,expr是食物的当前值(value)。在这种情况下,我知道,我可以简单地访问变量food,但是在某些情况下,该值可能无法再访问(array.shift等)。除了将expr移出到局部变量然后访问它之外,是否有直接访问caseexpr值的方法?罗亚附注我知道这个具体示例很简单,只是一个示例场景。 最佳答案

  8. ruby - 正则表达式 - 排除一个字符 - 2

    这是一个例子:s="abcd+subtext@example.com"s.match(/+[^@]*/)Result=>"+subtext"问题是,我不想在其中包含“+”。我希望结果是“潜台词”,没有+ 最佳答案 您可以在正则表达式中使用括号来创建匹配组:s="abcd+subtext@example.com"s=~/\+([^@]*)/&&$1=>"subtext" 关于ruby-正则表达式-排除一个字符,我们在StackOverflow上找到一个类似的问题:

  9. ruby - 如何遍历 Ruby 中所有正则表达式匹配的字符串? - 2

    我们有一个字符串:“”这个正则表达式://i如何从当前字符串中获取所有匹配项? 最佳答案 "".scan(//)参见scan在ruby​​-docs上 关于ruby-如何遍历Ruby中所有正则表达式匹配的字符串?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/6857852/

  10. Ruby 正则表达式匹配逗号,但忽略括号中的逗号 - 2

    我正在尝试通过正则表达式拆分参数列表。这是一个带有我的参数列表的字符串:"a=b,c=3,d=[1,3,5,7],e,f=g"我想要的是:["a=b","c=3","d=[1,3,5,7]","e","f=g"]我试过先行,但Ruby不允许使用动态范围后行,所以这行不通:/(?如何让正则表达式忽略方括号中的所有内容? 最佳答案 也许这样的东西对你有用:str.scan(/(?:\[.*?\]|[^,])+/)编辑再三考虑。简单的非贪婪匹配器在某些嵌套括号的情况下会失败。 关于Ruby正则

随机推荐