当前位置: 首页 > news >正文

《C++ Primer 第五版》initializer_list 涉及到的范围 for 循环(range-based for) 的语义差别

 背景代码

void error_msg(std::initializer_list<std::string> il) {for (const auto &elem : il) {   // 版本1std::cout << elem << " ";}for (const auto elem : il) {    // 版本2std::cout << elem << " ";}
}


1. for (const auto &elem : il)

  • elem 的类型const std::string&

  • 含义elem 是对 initializer_list 里面元素的常量引用,不会发生拷贝。

  • 特点

    • 避免了拷贝,效率高。

    • 无法修改 elem(因为加了 const)。


 2. for (const auto elem : il)

  • elem 的类型std::string

  • 含义:每次循环时,都会 拷贝 initializer_list 中的元素到 elem

  • 特点

    • elem 是一个新的局部对象,和容器里的元素无关。

    • 即使你去改 elem,也不会影响 il 里的内容。

    • 有性能损耗(每次循环都拷贝一个字符串)。


 直观对比图

写法elem 类型是否拷贝是否能修改用途
for (const auto &elem : il)const std::string&❌ 否❌ 否高效只读遍历
for (auto &elem : il)std::string&❌ 否✅ 是想要修改原元素时
for (const auto elem : il)std::string✅ 是❌ 否只读,但产生拷贝
for (auto elem : il)std::string✅ 是✅ 是(改的是副本)拷贝副本后修改

 举例演示

#include <iostream>
#include <initializer_list>
#include <string>
using namespace std;void error_msg(initializer_list<string> il) {cout << "[引用方式]:" << endl;for (const auto &elem : il) {cout << &elem << " ";   // 打印引用的地址}cout << endl;cout << "[拷贝方式]:" << endl;for (const auto elem : il) {cout << &elem << " ";   // 每次都是新地址(新对象)}cout << endl;
}int main() {error_msg({"hello", "world", "C++"});
}

输出(示意)

[引用方式]:
0x7ffc8a4a9d40 0x7ffc8a4a9d48 0x7ffc8a4a9d50
[拷贝方式]:
0x7ffc8a4a9c10 0x7ffc8a4a9c20 0x7ffc8a4a9c30

👉 引用方式:多个地址紧挨着,对应 initializer_list 内部存储。
👉 拷贝方式:每次循环 elem 都是新对象,地址完全不同。


 总结

  • for (const auto &elem : il)
    elemconst std::string&,高效,不拷贝。

  • for (const auto elem : il)
    elemstd::string,每次都会拷贝,效率低。

所以,一般遍历时推荐用 引用,除非你明确需要拷贝。

http://www.dtcms.com/a/351598.html

相关文章:

  • 车载铁框矫平机:把“钣金诊所”开到工地上
  • 【软考论文】论原型开发方法及其应用
  • Ubuntu 24.04 LTS 桌面版安装问题记录
  • 2025年8月27日,七月初五,生活指南
  • Python包管理与安装机制详解
  • pytorch-利用letnet5框架深度学习手写数字识别
  • 漫谈《数字图像处理》之霍夫变换发展历程与演进脉络
  • 类似ant design和element ui的八大Vue的UI框架详解优雅草卓伊凡
  • (vue)el-progress左侧添加标签/名称
  • C++学习(4)模板与STL
  • 虚幻5引擎:我们是在创造世界,还是重新发现世界?
  • 8.26 review
  • 【大前端】React统计所有网络请求的成功率、失败率以及统一入口处理失败页面
  • Ubuntu22.04安装OBS
  • 嵌入式系统学习Day23(进程)
  • 2025.8.26总结
  • 【系统架构设计(二)】系统工程与信息系统基础中:信息系统基础
  • 数据结构青铜到王者第四话---LinkedList与链表(1)
  • 【SystemUI】新增实体键盘快捷键说明
  • 【SystemUI】锁屏点击通知显示的解锁界面和通知重叠
  • [Sync_ai_vid] 唇形同步推理流程 | Whisper架构
  • 技术分享︱国产化突破:开源MDO工具链在新一代神威超算上的安装与调试
  • DevExpress WinForms中文教程:Data Grid - Excel样式的自定义过滤器对话框
  • 在Excel和WPS表格中输入分数的两种方法
  • 自然处理语言NLP: 基于双分支 LSTM 的酒店评论情感分析模型构建与实现
  • PostgreSQL快速入门
  • 会议室预约小程序主要功能及预约审批流程
  • Java大厂面试全解析:从Spring Boot到微服务架构实战
  • Hadoop MapReduce 任务/输入数据 分片 InputSplit 解析
  • ProfiNet转CAN/CANopen网关技术详解-三格电子