0

0

c++如何使用std::for_each_c++容器算法遍历详解【总结】

尼克

尼克

发布时间:2026-02-13 14:13:25

|

223人浏览过

|

来源于php中文网

原创

std::for_each 无法用 const_iterator 遍历并修改元素,因 const_iterator 解引用得 const t&,而 lambda 若声明 int& 参数则绑定失败;只读遍历时用普通迭代器配值参或 const 引用参数即可。

c++如何使用std::for_each_c++容器算法遍历详解【总结】

std::for_each 为什么遍历不了 vector 的 const_iterator?

因为 std::for_each 默认要求迭代器可解引用并赋值(即非 const),而你传了 cbegin()/cend() 或手动写了 const_iterator,却在 lambda 里试图修改元素——编译器会直接报错:assignment of read-only location

实际场景中,多数人想「只读遍历」,但误以为必须用 const 迭代器才能安全;其实只要 lambda 参数是 const T& 或值类型,用普通 begin()/end() 完全没问题,且更兼容。

  • 正确写法:std::for_each(v.begin(), v.end(), [](int x) { /* 只读用 x */ });
  • 错误写法:std::for_each(v.cbegin(), v.cend(), [](int& x) { x = 0; }); —— xconst int&,不能绑定到 int&
  • 若真要修改,别用 cbegin(),也别给 lambda 写 int& 参数,改用 int& 捕获或直接用普通迭代器

lambda 捕获方式影响 for_each 的副作用可见性

std::for_each 本身不保证 lambda 被调用几次(虽然实际是 N 次),但它不“返回”任何东西,所有状态变更必须靠捕获实现。很多人以为捕获 [&] 就万事大吉,结果发现变量没变——其实是 lambda 被复制了,而副本修改了局部副本。

典型表现:循环结束后计数器还是 0,或者容器没被修改。根本原因是 std::for_each 内部可能拷贝 lambda 对象(尤其在某些 libstdc++ 实现中)。

立即学习C++免费学习笔记(深入)”;

简篇AI排版
简篇AI排版

AI排版工具,上传图文素材,秒出专业效果!

下载
  • 安全做法:用 [&counter, &vec]() mutable { counter++; vec.push_back(...); } —— mutable 允许修改捕获的副本,但注意 vec 是引用,所以仍生效
  • 更稳方案:避免依赖 lambda 副作用,改用传统 for 循环,或把逻辑封装进函数对象(struct + operator()),显式控制拷贝语义
  • 别用 [=] 捕获需要修改的变量,除非你明确知道它会被拷贝且你希望修改副本

for_each 和 range-based for 性能差多少?

几乎没差别。现代编译器(GCC 9+、Clang 10+、MSVC 2019)对两者生成的汇编基本一致,都是简单指针/迭代器递增 + 解引用。所谓“for_each 更快”或“更慢”都是过时经验。

真正影响性能的是 lambda 是否内联、是否触发别名分析失败、以及容器类型(vector 快,list 慢)。但这些和遍历语法无关。

  • 优先选 range-based for:写起来直觉,调试时断点位置清晰,IDE 支持好
  • 只在需要复用算法逻辑(比如和 std::transform 统一接口)、或配合其他 STL 算法组合使用时,才用 std::for_each
  • 别为了“函数式风格”硬套 for_each,C++ 不是 Haskell,可读性比范式更重要

std::for_each 在 std::map 遍历时容易漏掉 key/value 类型

std::map<k>::iterator</k> 解引用得到的是 std::pair<const k v></const>,不是 std::pair<k></k>。很多代码直接写 [](auto p) { p.first = ...; },结果编译失败:assignment of read-only member 'std::pair<const int>::first'</const>

这不是 bug,是 map 设计使然:key 必须不可变,否则破坏红黑树结构。但新手常忽略这个 const,尤其从 vector 切换过来时。

  • 正确访问 key:[](const auto& p) { std::cout —— <code>p.firstconst K&,只读安全
  • 修改 value:[](auto& p) { p.second = 42; } —— p.secondV&,可写
  • 别用 auto p(值拷贝),尤其是 value 类型大时;用 const auto& pauto& p 明确意图

最常被忽略的点是:for_each 不检查迭代器有效性,也不做空范围保护。传入 v.end()v.begin() 顺序颠倒、或容器在 lambda 中被意外清空,都会导致未定义行为——它不会像 range-for 那样天然规避这类问题。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

543

2023.09.20

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

709

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

562

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

213

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

206

2025.08.29

lambda表达式
lambda表达式

Lambda表达式是一种匿名函数的简洁表示方式,它可以在需要函数作为参数的地方使用,并提供了一种更简洁、更灵活的编码方式,其语法为“lambda 参数列表: 表达式”,参数列表是函数的参数,可以包含一个或多个参数,用逗号分隔,表达式是函数的执行体,用于定义函数的具体操作。本专题为大家提供lambda表达式相关的文章、下载、课程内容,供大家免费下载体验。

211

2023.09.15

python lambda函数
python lambda函数

本专题整合了python lambda函数用法详解,阅读专题下面的文章了解更多详细内容。

191

2025.11.08

Python lambda详解
Python lambda详解

本专题整合了Python lambda函数相关教程,阅读下面的文章了解更多详细内容。

58

2026.01.05

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

22

2026.02.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 9.3万人学习

C 教程
C 教程

共75课时 | 4.7万人学习

C++教程
C++教程

共115课时 | 17.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号