右值和移动

发布时间:2026/8/10 18:57:26

右值和移动
值类别(value categories)lvalue通常可以放在等号左边的表达式, 左值例子变量函数或数据成员的名字返回左值引用的表达式如x, x 1, cout ’ . x 1 和 x返回的都是对x的int. x则返回的是int字符串字面量如 “hello world”rvalue通常只能放在等号右边的表达式, 右值glvaluegeneralized lvalue, 广义左值xvalueexpiring lvalue, 将亡值prvaluepure rvalue, 纯右值值类型(value type)是与引用类型(reference type)相对而言表明一个变量是代表实际数值还是引用另一个数值在C里所有的原生类型枚举结构联合类都代表值类型。只有引用()和指针( * ) 才是引用类型在Java里数字等原生类型是值类型类则属于引用类型在Python里一切类型都是引用类型引用类型(reference value)非常左值引用可以绑定非 const lvalue常左值引用可以绑定 lvalue, xvalue, prvalue非常右值引用可以绑定非 const xvalue, prvalue常右值引用可以绑定 xvalue, prvalue生命周期C的规则是一个临时对象(prvalue)会在包含这个临时对象的完整表达式估值完成后按生成顺序的逆序被销毁除非有生命周期延长发生C对临时对象有特殊的生命周期延长规则如果一个prvalue 被绑定到一个引用上它的生命周期则会延长到跟这个引用变量一样长result r process_shape( circle(), triangle());这条生命周期延长规则只对prvalue有效而对xvalue无效移动的意义右值引用的目的是实现移动而实现移动的意义是减少运行的开销移动案例string result string(Hello, ) name .;C11 以前的执行流程调用构造函数 string(const char*)生成临时对象 1Hello, 复制 1 次调用 operator(const string, const string)生成临时对象 2Hello, 复制 2 次name 复制 1 次调用 operator(const string, const char*)生成对象 3“Hello, 复制 3 次name 复制 2 次”. 复制 1 次假设返回值优化能够生效最佳情况对象 3 可以直接在 result 里构造完成临时对象 2 析构释放指向 string(Hello, ) name 的内存临时对象 1 析构释放指向 string(Hello, ) 的内存C11 以后的执行流程调用构造函数 string(const char*)生成临时对象 1Hello, 复制 1 次调用 operator(string, const string)直接在临时对象 1 上面执行追加操作并把结果移动到临时对象 2name 复制 1 次调用 operator(string, const char*)直接在临时对象 2 上面执行追加操作并把结果移动到 result“.” 复制 1 次临时对象 2 析构内容已经为空不需要释放任何内存临时对象 1 析构内容已经为空不需要释放任何内存如何实现移动除了拷贝构造函数外增加移动构造函数增加swap成员函数实现与另一个对象的快速交换在你的对象的名空间下应当有一个全局的 swap 函数调用成员函数 swap 来实现交换。支持这种用法会方便别人包括你自己在将来在其他对象里包含你的对象并快速实现它们的 swap 函数实现通用的 operator上面各个函数如果不抛异常的话应当标为 noexcept。这对移动构造函数尤为重要noexcept告诉编译器函数不会抛异常有利于编译器对程序做更多的优化以下情形鼓励用noexcept 移动构造函数move constructor、移动分配函数move assignment、析构函数destructor不要返回本地变量的引用在C编程中如果在函数内部返回一个指向本地对象的引用这是一个常见的错误int getLocalVariable() { int num 42; return num; // 错误返回了一个指向本地变量的引用 } int main() { int ref getLocalVariable(); // 错误引用指向已被销毁的本地变量 cout ref endl; // 可能输出任意值因为引用指向已被销毁的内存 }引用坍缩又称“引用折叠”当一个泛型函数模板中的类型参数与实际参数类型相同时编译器会进行类型折叠即将模板中的类型参数替换为实际参数类型从而简化代码。template typename T void process_shape(T shape) { puts(Processing shape); } void foo() { process_shape(circle()); // 调用 process_shape(circle()) process_shape(triangle()); // 调用 process_shape(triangle()) }当我们调用 process_shape(circle()) 和 process_shape(triangle()) 时编译器会根据实际参数类型进行类型折叠即 T 的推导结果分别是 circle 和 triangle在有模板的代码中当类型推导结果相同时编译器会将模板中的类型参数替换为实际参数类型从而简化代码。这个现象在实际编程中经常会遇到完美转发定义一个函数模板该函数模板可以接收任意类型参数然后将参数转发发给其他目标函数且保证目标函数接受的参数其类型与传递给模板函数的类型相同对于一个函数如果形参是右值引用但在函数体内这个“右值引用”实际上是一个左值变量然后函数内再有一个函数传入这个参数那么就会调用对应的左值引用版本而完美转发的意义就相当于做一次类型转换让这个参数保持一开始传入时的左值右值类别移动案例#include string #include ctime #include chrono #include iostream void func1(std::string s) { } void func2(const std::string s) { } void test2() { std::string a hello; auto start std::chrono::system_clock::now(); for (size_t i 0; i 20000000; i) { func1(std::string(hello)); } auto end std::chrono::system_clock::now(); std::chrono::durationdouble elapsed_seconds end - start; std::cout elapsed time: elapsed_seconds.count() s\n; start std::chrono::system_clock::now(); for (size_t i 0; i 20000000; i) { func2(std::string(hello)); } end std::chrono::system_clock::now(); elapsed_seconds end - start; std::cout elapsed time: elapsed_seconds.count() s\n; } // 改进版本 void test3() { std::string a hello; auto start std::chrono::system_clock::now(); for (size_t i 0; i 20000000; i) { func1(a); } auto end std::chrono::system_clock::now(); std::chrono::durationdouble elapsed_seconds end - start; std::cout elapsed time: elapsed_seconds.count() s\n; start std::chrono::system_clock::now(); for (size_t i 0; i 20000000; i) { func2(a); } end std::chrono::system_clock::now(); elapsed_seconds end - start; std::cout elapsed time: elapsed_seconds.count() s\n; } int main() { std::cout ---- test2 测试时间 ---- std::endl; test2(); std::cout ---- test3 测试时间 ---- std::endl; test3(); }结果:---- test2 测试时间 ---- elapsed time: 1.8719s elapsed time: 1.90104s ---- test3 测试时间 ---- elapsed time: 0.424229s elapsed time: 0.0873127s问题: 在test2 case 中为什么func1比func2快func1(string(“func1”))时传入的参数是一个右值.同时在函数调用中临时对象的所有权会被转移给函数的参数s因此会发生一次移动构造操作func2(string(“func2”))时传入的参数也是一个右值虽然函数参数s是通过常量引用传递的但临时对象string(“func2”)可以绑定到常量引用因此不会发生拷贝操作。为什么test3整体时间比test2快?例如func1(a)和func2(a)传入的参数是一个左值因为a是一个已命名的变量它具有持久性并且可以被多次使用. 原因在于使用已命名的变量作为参数时可以直接进行拷贝构造而不需要进行额外的临时对象的创建和销毁参考资料C右值引用

相关新闻

AI写作率检测踩坑:我改了3版文档反而把检测率越改越高

AI写作率检测踩坑:我改了3版文档反而把检测率越改越高

2026/8/10 18:57:26

上周赶省级技术专项的申报材料,熬了三个大夜交上去,隔天就被行政打回,说提交端口的AI写作率检测直接触发了红色预警,要求3天内提交原创说明加修改后的版本。当时整个人都傻了,7000多字的材料我只是用GPT搭了个三级框架…

云南财经大学的校园网深澜认证协议

云南财经大学的校园网深澜认证协议

2026/8/10 18:57:26

简单介绍了云财关于校园网的加密 免责声明 本文旨在分析校园网认证协议的技术原理,供教育交流与网络优化参考,严禁用于商业用途或任何违反《网络安全法》《著作权法》及学校规定的行为。文中部分描述可能与原有系统关联,相关权利归属开发者所…

LightCTR深度解析:轻量级CTR预测框架如何革新分布式机器学习?

LightCTR深度解析:轻量级CTR预测框架如何革新分布式机器学习?

2026/8/10 18:47:25

LightCTR深度解析:轻量级CTR预测框架如何革新分布式机器学习? 【免费下载链接】LightCTR Lightweight and Scalable framework that combines mainstream algorithms of Click-Through-Rate prediction based computational DAG, philosophy of Paramete…

tf_efficientnet_b2.ns_jft_in1k:如何用9.1M参数实现高效图像分类?新手入门指南

tf_efficientnet_b2.ns_jft_in1k:如何用9.1M参数实现高效图像分类?新手入门指南

2026/8/10 20:07:31

tf_efficientnet_b2.ns_jft_in1k:如何用9.1M参数实现高效图像分类?新手入门指南 【免费下载链接】tf_efficientnet_b2.ns_jft_in1k 项目地址: https://ai.gitcode.com/hf_mirrors/timm/tf_efficientnet_b2.ns_jft_in1k tf_efficientnet_b2.ns_jf…

69万亿Token在跨境流动:你的AI账单,已经算不清了

69万亿Token在跨境流动:你的AI账单,已经算不清了

2026/8/10 20:07:31

上周,全球AI模型通过OpenRouter产生了69万亿Token的调用量。其中中国模型占34.25万亿,美国模型占9.17万亿。 这是一个宏观数字。但如果你把镜头拉近,拉近到一家正在使用AI的企业——可能就是你的企业——会发现这69万亿里,有相当…

【AI大模型应用开发】【项目实战】Agent智扫引擎项目知识整体知识总结以及为什么要使用各个方案进行项目开发与设计

【AI大模型应用开发】【项目实战】Agent智扫引擎项目知识整体知识总结以及为什么要使用各个方案进行项目开发与设计

2026/8/10 20:07:31

一. 架构决策:为什么用 Agent,而不是传统流程?意图的复杂性与动态性: 传统客服机器人基于意图识别(Intent Classification) 固定SOP流转,但在该项目场景中,用户的表达往往是多意图混合且带有上下…

革命性Deepfake质量评估工具:Deepfake-QualityAssess2.0-85M-ONNX完全指南

革命性Deepfake质量评估工具:Deepfake-QualityAssess2.0-85M-ONNX完全指南

2026/8/10 20:07:31

革命性Deepfake质量评估工具:Deepfake-QualityAssess2.0-85M-ONNX完全指南 【免费下载链接】Deepfake-QualityAssess2.0-85M-ONNX 项目地址: https://ai.gitcode.com/hf_mirrors/prithivMLmods/Deepfake-QualityAssess2.0-85M-ONNX Deepfake-QualityAssess2…

deit_base_distilled_patch16_224.fb_in1k模型详解:从配置文件到特征提取的完整工作流

deit_base_distilled_patch16_224.fb_in1k模型详解:从配置文件到特征提取的完整工作流

2026/8/10 20:07:31

deit_base_distilled_patch16_224.fb_in1k模型详解:从配置文件到特征提取的完整工作流 【免费下载链接】deit_base_distilled_patch16_224.fb_in1k 项目地址: https://ai.gitcode.com/hf_mirrors/timm/deit_base_distilled_patch16_224.fb_in1k deit_base_d…

Prometheus 监控体系深度部署:一次故障复盘能留下什么

Prometheus 监控体系深度部署:一次故障复盘能留下什么

2026/8/10 19:57:29

Prometheus 监控体系深度部署:一次故障复盘能留下什么 重大故障后的复盘常会遇到几个问题:告警延迟、仪表盘未反映异常,以及告警过多导致首个故障点难以识别。 复盘应沉淀为可执行的改进:更新 Prometheus 告警规则、保留完整证据链…

比较好的亚太EMBA,问了6位校友师资差别真的挺大

比较好的亚太EMBA,问了6位校友师资差别真的挺大

2026/8/10 5:58:32

比较好的亚太EMBA核心差异先看什么?对于希望兼顾工作与系统管理能力提升的亚太区高管而言,筛选匹配度高的EMBA项目时,师资配置是决定学习体验与实际收获的核心要素之一。我们结合3-4个公开信息透明、办学历史较长的亚太区主流EMBA项目特点&am…

备考3个月对比6份资料 海外游学的亚洲EMBA面试注意点

备考3个月对比6份资料 海外游学的亚洲EMBA面试注意点

2026/8/10 7:54:12

备考海外游学的亚洲EMBA面试,核心要围绕项目国际化设计逻辑、个人跨文化管理经验匹配度两个维度准备,避免把游学模块等同于普通旅游参访的认知偏差。不少备考者花3个月对比6份资料,却容易忽略面试官对“国际视野落地能力”的考察——比如香港…

比较好的国内EMBA,问了二十位校友聊透人脉价值

比较好的国内EMBA,问了二十位校友聊透人脉价值

2026/8/10 7:19:21

比较好的国内EMBA核心差异体现在哪些方面?比较好的国内EMBA的核心长期价值,很大程度上依托于校友网络的连接质量与资源生态的活跃度,这也是不少高管在择校时优先考量的因素。我们结合3-4个市场关注度较高的项目公开信息,从课程、师…

Prometheus 监控体系深度部署:选型别只看功能清单

Prometheus 监控体系深度部署:选型别只看功能清单

2026/8/10 0:06:33

Prometheus 监控体系深度部署:选型别只看功能清单 选型场景:小规模集群直接部署 Thanos 的代价 如果为解决 15 天本地存储限制,直接部署 Thanos Sidecar、Store Gateway、Querier、Compactor、Ruler、Bucket Web 并接入 S3,就需…

ELK 日志分析平台与全链路追踪:代码评审该盯住哪些细节

ELK 日志分析平台与全链路追踪:代码评审该盯住哪些细节

2026/8/10 0:06:33

ELK 日志分析平台与全链路追踪:代码评审该盯住哪些细节 场景示例:一条 2MB 日志影响 Elasticsearch 写入 一个上传接口若执行 log.Info("Request dumped: ", r.Body),会将 2MB 的二进制 Body 写入日志。高并发下,这类超…

从零到一构建开源项目的完整历程:代码评审该盯住哪些细节

从零到一构建开源项目的完整历程:代码评审该盯住哪些细节

2026/8/10 0:06:33

从零到一构建开源项目的完整历程:代码评审该盯住哪些细节 项目进入稳定版本后,外部 Pull Request(PR)会带来新的协作成本。大范围改动混入风格重构,或修复局部问题时修改公共函数签名,都可能扩大评审和兼容…

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

2026/8/8 5:07:31

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…

导师推荐!2026最新AI论文工具测评与实用推荐

导师推荐!2026最新AI论文工具测评与实用推荐

2026/8/9 13:42:46

2026年真正好用的AI论文工具,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

告别游戏崩溃:XCOM 2模组管理器的智能革命

告别游戏崩溃:XCOM 2模组管理器的智能革命

2026/8/8 2:30:15

告别游戏崩溃:XCOM 2模组管理器的智能革命 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/gh_mirrors/xc/xcom2-lau…