C++中lambda使用mutable关键字详解

news2024/9/21 10:46:35

C++中lambda使用mutable关键字详解

在《C++初学者指南-5.标准库(第二部分)–更改元素算法》中,讲“generate”算法时有下面这段代码:

auto gen = [i=0]() mutable { i += 2; return i; };
std::vector<int> v;
v.resize(7,0);
generate(begin(v)+1, begin(v)+5, gen);
for (int x : v) { cout << x << ' '; }  // 0 2 4 6 8 0 0

第一行的lambda中使用了mutable关键字,很多人不知道其中含义,这里详细解释一下。
lambda表达式,最终会被C++编译器转换成一个匿名函数类,函数类又叫仿函数,就是重载了函数调用符:operator()的类。
可以像函数一样使用这个类的对象实例。在编译器的转换中会默认将值捕获方式的lambda转换的operator()函数的cv限定符设为const,
也就是operator()函数内是不能修改捕获的变量值的,匿名类中的重载operator()成员函数就是lambda函数本体。如果lambda表达式未使用mutable修饰,则operator()函数是const类型的,使用mutable可以解除该限制。这样就可以在lambda内修改捕获的变量值了。
我们通过Complie Explorer的反汇编功能可以清楚的看到这一点:

#include <vector>
#include <iostream>
#include <algorithm>

int main () {
    auto gen = [i=0]() mutable { i=i+2; return i; };
    std::cout << gen() << "\n";
}

反汇编后如下:

main::{lambda()#1}::operator()():    //注意operator()函数定义时没有const
        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-8], rdi
        mov     rax, QWORD PTR [rbp-8]
        mov     eax, DWORD PTR [rax]
        lea     edx, [rax+2]
        mov     rax, QWORD PTR [rbp-8]
        mov     DWORD PTR [rax], edx
        mov     rax, QWORD PTR [rbp-8]
        mov     eax, DWORD PTR [rax]
        pop     rbp
        ret
.LC0:
        .string "\n"
main:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        mov     DWORD PTR [rbp-4], 0
        lea     rax, [rbp-4]
        mov     rdi, rax
        call    main::{lambda()#1}::operator()()          
        mov     esi, eax
        mov     edi, OFFSET FLAT:std::cout
        call    std::basic_ostream<char, std::char_traits<char> >::operator<<(int)
        mov     esi, OFFSET FLAT:.LC0
        mov     rdi, rax
        call    std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
        mov     eax, 0
        leave
        ret

我们再看一下不加mutable的代码:

#include <vector>
#include <iostream>
#include <algorithm>

int main () {
    auto gen = [i=0]() { return i; };
    std::cout << gen() << "\n";
}

反汇编如下:

main::{lambda()#1}::operator()() const:  //注意定义函数时有const
        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-8], rdi
        mov     rax, QWORD PTR [rbp-8]
        mov     eax, DWORD PTR [rax]
        pop     rbp
        ret
.LC0:
        .string "\n"
main:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        mov     DWORD PTR [rbp-4], 0
        lea     rax, [rbp-4]
        mov     rdi, rax
        call    main::{lambda()#1}::operator()() const
        mov     esi, eax
        mov     edi, OFFSET FLAT:std::cout
        call    std::basic_ostream<char, std::char_traits<char> >::operator<<(int)
        mov     esi, OFFSET FLAT:.LC0
        mov     rdi, rax
        call    std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
        mov     eax, 0
        leave
        ret

如果文章对您有用,请随手点个赞,谢谢!^_^
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

(南京观海微电子)——LCD OTP(烧录)介绍

OTP OTP只是一种存储数据的器件&#xff0c;全写:ONETIMEPROGRAM。 OTP目的&#xff1a;提高产品的一致性 客户端的接口不支持和我们自己的产品IC之间通信&#xff0c;即不支持写初始化&#xff0c;所以产品的电学功能以及光学特性需要固化在IC中&#xff0c;所以需要我们来进行…

青甘环线游记|day(1)|兰州

出发 下午1点&#xff0c;登机。航班经停万州&#xff0c;再到兰州。下图为飞机上拍的照片&#xff0c;不知道为什么窗户上有结晶的东西&#xff08;&#xff1f;&#xff09; 在飞机上拍的航线图&#xff0c;但是有点模糊。飞机上有提供午餐。4点左右到达万州 在飞机上好像…

08 Redis Set类型操作与使用场景

Redis Set类型操作与使用场景 一、Set类型操作 ​ Redis的Set结构与Java中的HashSet类似&#xff0c;可以看做是一个value为null的HashMap。因为也是一个hash表&#xff0c;因此具备与HashSet类似的特征&#xff1a; ​ 无序 ​ 元素不可重复 ​ 查找快 ​ 支持交集、并集…

Tomcat 8.5 下载、安装、启动及各种问题

&#x1f970;&#x1f970;&#x1f970;来都来了&#xff0c;不妨点个关注叭&#xff01; &#x1f449;博客主页&#xff1a;欢迎各位大佬!&#x1f448; 本期内容主要介绍 Tomcat 8 的安装&#xff0c;以及可能会遇到的问题 文章目录 1. Tomcat 安装2. 可能会遇到的问题2.…

pip‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。

重新设置一下环境变量。 注意&#xff0c;这里后面没有斜杠 我之前就是因为环境变量中&#xff0c;这两行最后都有斜杠&#xff0c;导致提示pip‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。

Multi-AP

1. Multiple-BSSID 和Multi-VAP Multiple-BSSID 和Multi-VAP差异&#xff1a; Multi-VAP&#xff1a; 每个AP独自发送beacon帧&#xff1b; Multiple-BSSID&#xff1a; 所有AP公用一个beacon帧。 1.1 Multi-VAP 如果您使用过 Wi-Fi &#xff08;2.4/5.0GHz&#xff09;&am…

著名ROM修改社区停止运营 管理员与继任者互相指责

运营近二十年的知名ROM修改社区网站Romhacking.net即将关闭新内容的提交和更新。网站创始人Nightcrawler表示&#xff0c;网站已经“几乎完成了最初设定的所有目标&#xff0c;并且远远超出了预期。”然而&#xff0c;根据其他网站工作人员的说法&#xff0c;事情似乎没那么简单…

C++ 重要特性探究

shared_from_this 使用分析 场景 类的成员函数需要获取指向自身的shared_ptr的时候类成员函数传递shared_ptr给其他函数或者对象的时候&#xff0c;目的是为了管理对象生命周期使用方法 首先类必须继承 std::enable_shared_from_this<T>必须使用 shared_from_this 获取指…

Arduino PID库 (2) –微分导致的过冲

Arduino PID库 &#xff08;2&#xff09; – Derivative Kick 参考&#xff1a;手把手教你看懂并理解Arduino PID控制库——微分冲击 pid内容索引-CSDN博客 Arduino PID库 &#xff08;1&#xff09;– 简介 问题 此修改将稍微调整derivative term。目标是消除一种称为“…

RocketMQ消息汇总

当物理文件删除了 队列中的下标的消息也被删除了 但是即使物理删除了 队列中的偏移量还是会持续上升每天凌晨4点 定时清理 在 RocketMQ 中&#xff0c;消息的物理删除是通过定期清理 CommitLog 文件来实现的。CommitLog 文件中存储的是所有主题和队列的消息&#xff0c;一旦这…

关于图片导入Eagle弹出“抱歉,eagle发生了一些问题”的解决办法 | 如何查看Eagle调试报告查询错误文件方法

教程不易&#xff0c;希望得到关注 先说解决办法 使用格式工厂将所有图片或报错图片文件再次转为JPG文件&#xff0c;即可正常导入。 官网入口 http://www.pcgeshi.com/ 吐槽一下现在搜索软件搜“格式工厂官网”第一页全是盗版软件和流氓网页&#xff0c;什么什么金X 风X格式…

使用 Streamlit 和 Python 构建 Web 应用程序

一.介绍 在本文中&#xff0c;我们将探讨如何使用 Streamlit 构建一个简单的 Web 应用程序。Streamlit 是一个功能强大的 Python 库&#xff0c;允许开发人员快速轻松地创建交互式 Web 应用程序。Streamlit 旨在让 Python 开发人员尽可能轻松地创建 Web 应用程序。以下是一些主…

TCP/UDP Socket 测试小工具,作为网工不可以不知道

背景 阿祥今天推荐一款TCP/UDP Socket 测试工具&#xff0c;所谓TCP/IP调试工具是用于在TCP/UDP的应用层上进行通信连接、数据传输的Windows工具。所谓应用层上就是说&#xff0c;TCP调试工具是不涉及TCP/IP协议层实现的问题&#xff0c;而只是利用TCP/IP进行数据传输的工具。 …

建模杂谈系列246 数据模型

说明 如果说微服务化(API接口、Web页面、Docker镜像)是架构方面的基准&#xff0c;那么数据模型就是逻辑处理方面的基准 内容 以下是一个样例&#xff1a; import redef extract_utf8_chars(input_string None):# 定义一个正则表达式&#xff0c;用于匹配所有的UTF-8字符utf…

OpenStack Yoga版安装笔记(十一)nova安装(上)

1、官方文档 OpenStack Installation Guidehttps://docs.openstack.org/install-guide/ 本次安装是在Ubuntu 22.04上进行&#xff0c;基本按照OpenStack Installation Guide顺序执行&#xff0c;主要内容包括&#xff1a; 环境安装 &#xff08;已完成&#xff09;OpenStack…

一文详解大模型蒸馏工具TextBrewer

原文&#xff1a;https://zhuanlan.zhihu.com/p/648674584 本文分享自华为云社区《TextBrewer&#xff1a;融合并改进了NLP和CV中的多种知识蒸馏技术、提供便捷快速的知识蒸馏框架、提升模型的推理速度&#xff0c;减少内存占用》&#xff0c;作者&#xff1a;汀丶。 TextBre…

谷粒商城实战笔记-122~124-全文检索-ElasticSearch-分词

文章目录 一&#xff0c;122-全文检索-ElasticSearch-分词-分词&安装ik分词二&#xff0c;124-全文检索-ElasticSearch-分词-自定义扩展词库1&#xff0c;创建nginx容器1.1 创建nginx文件夹1.2 创建nginx容器获取nginx配置1.3 复制nginx容器配置文件1.4 删除临时的nginx容器…

《Milvus Cloud向量数据库指南》——什么是高可用:深入理解数据库系统中的高可用性架构

什么是高可用:深入理解数据库系统中的高可用性架构 在信息技术日新月异的今天,高可用性(High Availability,简称HA)已成为衡量一个系统,尤其是数据库系统稳定性和可靠性的重要标准。高可用性的核心目标在于确保系统能够持续不断地提供服务,最大限度地减少因维护活动、硬…

从零开始安装Jupyter Notebook和Jupyter Lab图文教程

前言 随着人工智能热浪&#xff08;机器学习、深度学习、卷积神经网络、强化学习、AGC以及大语言模型LLM, 真的是一浪又一浪&#xff09;的兴起&#xff0c;小伙伴们Python学习的热情达到了空前的高度。当我20年前接触Python的时候&#xff0c;做梦也没有想到Python会发展得怎么…

【初阶数据结构题目】10. 链表的回文结构

链表的回文结构 点击链接做题 思路1&#xff1a;创建新的数组&#xff0c;遍历原链表&#xff0c;遍历原链表&#xff0c;将链表节点中的值放入数组中&#xff0c;在数组中判断是否为回文结构。 例如&#xff1a; 排序前&#xff1a;1->2->2->1 设置数组来存储链表&a…