C++11_lambda表达式

文章目录

  • 一、lambda表达式
    • 1.lambda的组成
      • 2.[capture-list] 的其他使用方法
      • 2.1混合捕捉
  • 二、lambda表达式的使用场景
    • 1.替代仿函数
  • 总结


一、lambda表达式

lambda表达式是C++11新引入的功能,它的用法与我们之前学过的C++语法有些不同。

1.lambda的组成

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

[capture-list] : 捕捉列表,该列表总是出现在lambda函数的开始位置,编译器根据[]来
判断接下来的代码是否为lambda函数,捕捉列表能够捕捉上下文中的变量供lambda
函数使用。
(parameters):参数列表。与普通函数的参数列表一致,如果不需要参数传递,则可以
连同()一起省略
mutable:默认情况下,lambda函数总是一个const函数,mutable可以取消其常量
性。使用该修饰符时,参数列表不可省略(即使参数为空)。
->returntype:返回值类型。用追踪返回类型形式声明函数的返回值类型,没有返回值时此部分可省略。返回值类型明确情况下,也可省略,由编译器对返回类型进行推
导。
{statement}:函数体。在该函数体内,除了可以使用其参数外,还可以使用所有捕获到的变量

示例代码如下

	int a = 2;int b = 3;auto func1 = [](int a, int b)->int {return a + b;};std::cout << func1(a, b) << std::endl;

首先看示例代码
“[capture-list]”: 下面再讲,这里需要记住是[]即便里面没有内容也不可以省略。
“(parameters)” :很像我们函数的参数列表,而实际上在这里的作用也是如此。如果没有参数,那么可以连同()一起省略
“->returntype” :->返回值类型,一般都可以省略,但是推荐不省略。
“{}”: 可以理解为函数体,内部写自己想实现的功能。


示例代码如下

	int a = 2;int b = 3;auto func1 = [a, b]()->int {++a;  编译报错++b;  编译报错return a + b;};auto func2 = [a, b]()mutable->int {++a;   运行通过++b;return a + b;};func2(); //调用func2std::cout << " func2: " << a << " - " << b << std::endl;

“[capture-list]”: 捕捉的是现有变量让它们能在函数体内运行。
func1 和 func2 唯一的区别就是有没有加mutable(可变的)。默认情况下,lambda函数总是一个const函数,mutable可以取消其常量
性。 所以func2使用mutable就可以改变函数体内a和b的值。

那么这里提出疑问,外面的a和b的值是否被修改? -> 不会
在这里插入图片描述

因为这里其实是一个传值拷贝,如果你需要在lambda内部改变外面的a,b,可以使用引用

	int a = 2;int b = 3;auto func1 = [a, b]()mutable->int {++a;++b;return a + b;};func1(); //调用func1std::cout << " func1: " << a << " - " << b << std::endl;auto func2 = [&a, &b]()mutable->int {++a;++b;return a + b;};func2(); //调用func2std::cout << " func2: " << a << " - " << b << std::endl;

在这里插入图片描述

2.[capture-list] 的其他使用方法

“[=]”:根据上下文全部以值传递捕捉变量
"[&]':根据上下文全部以引用传递捕捉变量

	int a = 1;int b = 2;double d = 2.2;std::string str = "hello world";auto func1 = [=]()mutable {  //根据上下文全部以值传递捕捉变量std::cout << a << " " << b << " " << d << " " << str << std::endl;a = 10;};func1();std::cout << "a: " << a << std::endl << std::endl;;auto func2 = [&]()mutable {  //根据上下文全部以引用传递捕捉变量std::cout << a << " " << b << " " << d << " " << str << std::endl;a = 10;};func2();std::cout << "a: " << a << std::endl;

在这里插入图片描述


2.1混合捕捉

	int a = 1;int b = 2;double d = 2.2;std::string str = "hello world";auto func1 = [= , &a]()mutable{//除a以引用传递捕捉,其他根据上下文全部以值传递捕捉变量std::cout << a << " " << b << " " << d << " " << str << std::endl;a = 10;};func1();std::cout << "a: " << a << std::endl << std::endl;;auto func2 = [&, a]()mutable{//除a以值传递捕捉,其他根据上下文全部以引用传递捕捉变量std::cout << a << " " << b << " " << d << " " << str << std::endl;a = 1;};func2();std::cout << "a: " << a << std::endl;

在这里插入图片描述

二、lambda表达式的使用场景

1.替代仿函数

仿函数我们之前对于实现很多STL中的容器的排序都使用过,应该不陌生,而lambda表达式我们看来其实也跟一个函数差不多,一样有参数,一样有返回值,一样能写函数体,所以我们就可以使用lambda来取代仿函数

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<functional>
struct Goods {Goods(std::string name, double price, size_t evaluation):_name(name),_price(price),_evaluation(evaluation) {}std::string _name;double _price;size_t _evaluation;
};int main()
{std::vector<Goods> v = {{ "苹果", 2.1, 5 },{ "香蕉", 3, 4 }, { "橙子", 2.2, 3 },{ "菠萝",1.5,4 }};std::sort(v.begin(), v.end(), [](const Goods& s1, const Goods& s2)->bool {return s1._name < s2._name;}); // 字符串升序for (auto& a : v){std::cout << a._name << " - " << a._price << " - " << 	a._evaluation << std::endl;}std::cout << std::endl;std::sort(v.begin(), v.end(), [](const Goods& s1, const Goods& s2)->bool {return s1._name > s2._name;}); // 字符串降序for (auto& a : v){std::cout << a._name << " - " << a._price << " - " << a._evaluation << std::endl;}std::cout << std::endl;std::sort(v.begin(), v.end(), [](const Goods& s1, const Goods& s2)->bool {return s1._price < s2._price;}); // 价格升序for (auto& a : v){std::cout << a._name << " - " << a._price << " - " << a._evaluation << std::endl;}std::cout << std::endl;std::sort(v.begin(), v.end(), [](const Goods& s1, const Goods& s2)->bool {return s1._evaluation < s2._evaluation;}); // 评价升序for (auto& a : v){std::cout << a._name << " - " << a._price << " - " << a._evaluation << std::endl;}std::cout << std::endl;return 0;
}

在这里插入图片描述

总结

这些就是lambda表达式的全部内容,lambda表达式还是十分有用的,对于一些我们只需要运行一遍的函数或者是对象内传仿函数类型,我们都可以使用使用lambda表达式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/339542.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

有免费仓库出入库管理软件推荐吗?

有免费仓库出入库管理软件推荐吗&#xff1f; 对于希望仓库管理系统“简单易上手”的使用者来说&#xff0c;能够实现扫码出入库的系统无疑是最优选。这种方式以其直观的操作和高效的流程&#xff0c;极大地简化了仓库管理&#xff0c;为用户提供了许多实际的便利。 像我们公…

android 实时流媒体 实时流媒体播放

场景描述 将实时流采集终端的视频数据实时推送到另外一个&#xff08;多个&#xff09;播放终端&#xff0c;完成远距离实时视频播放的功能。典型场景&#xff1a; &#xff08;1&#xff09;远程查看监控摄像头。选择指定摄像头&#xff0c;将该摄像头采集到的实时数据推送到…

k8s的存储卷、数据卷---动态PV创建

当发布PVC之后可以生成PV&#xff0c;还可以在动态服务器上直接生成挂载目录。PVC直接绑定和使用PV。 动态PV需要两个组件 存储卷插件&#xff1a;Provisioner(存储分配器)根据定义的属性创建PV StorageClass&#xff1a;定义属性 存储卷插件 存储卷插件&#xff1a;k8s本…

【谭浩强C程序设计 学习辅导第3章】最简单的C程序设计——顺序程序设计(含详细源码)

文章目录 一、 顺序程序设计题的解题思路及注意事项解题思路注意事项 二、源码讲解第3章源码文件构成&#xff1a;main.c 文件内容说明chap3.c源码实现chap3.h声明头文件测试结果展示源码链接 说明&#xff1a;本学习辅导题适用于谭浩强教辅第四版。 一、 顺序程序设计题的解题…

【数据库】视图索引执行计划多表查询笔试题

文章目录 一、视图1.1 概念1.2 视图与数据表的区别1.3 优点1.4 语法1.5 实例 二、索引2.1 什么是索引2.2.为什么要使用索引2.3 优缺点2.4 何时不使用索引2.5 索引何时失效2.6 索引分类2.6.1.普通索引2.6.2.唯一索引2.6.3.主键索引2.6.4.组合索引2.6.5.全文索引 三、执行计划3.1…

2023年全国职业院校技能大赛(高职组)“云计算应用”赛项赛卷⑩

2023年全国职业院校技能大赛&#xff08;高职组&#xff09; “云计算应用”赛项赛卷10 目录 需要竞赛软件包环境以及备赛资源可私信博主&#xff01;&#xff01;&#xff01; 2023年全国职业院校技能大赛&#xff08;高职组&#xff09; “云计算应用”赛项赛卷10 模块…

【精选】小白 kali环境的linux基础设置 (超详细)

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【python】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏…

What does `rpm -ivh` do?

rpm -ivh 安装 并 显示安装进度 (–install–verbose–hash) rpm -ivh /media/cdrom/RedHat/RPMS/samba-3.0.10-1.4E.i386.rpm 安装rpm -ivh --relocate //opt/gaim gaim-1.3.0-1.fc4.i386.rpm 指定安装到 /opt/gaim[Ref] rpm -uvh和-ivh有什么区别以及zabbix 安…

3小时玩转微服务架构中的分布式流量防护

以下是我在极客时间带名企师友班时讲课的PPT&#xff0c;现在开放出来给广大技术爱好者&#xff0c;希望对大家有帮助&#xff0c;如果大家觉得有帮助&#xff0c;可以给一个免费的关注和点赞。 另外我的新书RocketMQ消息中间件实战派上下册&#xff0c;在京东已经上架啦&#…

EasyPOI导出报表(二)-合并单元格

上篇讲到EasyPOI导出常规报表&#xff0c;本篇是在此基础上再增加新的东西-合并单元格&#xff0c;这个功能在需求中也很常见。 这里我直接贴逻辑代码&#xff1a; EasyPOI工具类加上如下方法 /*** Description: excel导出-合并单元格* param[1] list 数据列表* param[2] tit…

动态画出300以内的质数曲线图

用python&#xff1a; # -*- coding: utf-8 -*- import matplotlib.pyplot as plt import numpy as np import time import os# 定义一个函数来检查一个数是否为质数 def is_prime(n): if n < 2: return False for i in range(2, int(n ** 0.5) 1): if n % i …

【LeetCode】第二高的薪水(数据库)

目录 题目&#xff1a; 方法一 验证一&#xff1a; 验证二&#xff1a; 方法二 验证一&#xff1a; 验证二&#xff1a; 方法三 验证一&#xff1a; 验证二&#xff1a; 题目&#xff1a; 方法一 SELECT DISTINCT Salary AS SecondHighestSalary FROM Employee O…