推荐优先用 range-based for(如 for (const auto& p : my_map)),语义清晰且避免拷贝;需条件跳过或删除时用迭代器,注意 erase 后迭代器失效规则;for_each 适合无状态批量操作;反向遍历必须用 rbegin/rend。

用 range-based for 遍历 map 最简洁
现代 C++(C++11 起)推荐优先用 for (const auto& p : my_map),它自动解包为 std::pair,语义清晰且不易出错。
- 必须用
const auto&或auto&,避免拷贝整个pair(尤其 value 是大对象时) - 键是
const的,直接写p.first、p.second即可访问 - 如果需要修改 value,用
auto&;但不能改p.first,否则编译失败(map 键不可变)
std::map<int std::string> m = {{1,"a"}, {2,"b"}};
for (const auto& p : m) {
std::cout <h3>用迭代器遍历支持条件跳过和删除</h3>
<p>当需要在遍历时做判断、提前退出,或边遍历边 <code>erase</code> 元素时,必须用显式迭代器。注意 <code>erase</code> 后迭代器失效规则:</p>
<ul>
<li>
<code>it = m.erase(it)</code> 是安全的,返回下一个有效迭代器(C++11 起)</li>
<li>
<code>m.erase(it++)</code> 也常见,但需确保 <code>it</code> 不是 <code>m.end()</code> 才能自增</li>
<li>千万别写 <code>m.erase(it); ++it;</code> —— <code>erase</code> 后 <code>it</code> 已失效,再自增是未定义行为</li>
</ul>
<pre class="brush:php;toolbar:false;">for (auto it = m.begin(); it != m.end(); ) {
if (it->second == "skip") {
it = m.erase(it); // 安全删除并移动
} else {
std::cout first <h3>用 std::for_each + lambda 做无状态批量操作</h3><p>适合只读、无副作用、逻辑较短的场景,比如打印、统计、校验。相比 range-for,它更函数式,但可读性未必更高。</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/gongju/2823" title="C++14"><img
src="https://img.php.cn/upload/manual/001/431/639/6ac8b33c327c4749.png" alt="C++14" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="overflowclass">C++14</a>
<p class="overflowclass">C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。</p>
</div>
<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
- lambda 参数类型必须匹配:通常写
const std::pair或直接用& auto& - 不能在 lambda 内修改 map 结构(如 insert/erase),否则迭代器可能失效
- 若需捕获外部变量做累加,记得加
&或=捕获说明符
int count = 0;
std::for_each(m.begin(), m.end(), [&count](const auto& p) {
if (!p.second.empty()) ++count;
});
反向遍历要用 rbegin/rend,别用 --end()
想从最大键开始遍历?必须用反向迭代器 rbegin()/rend(),而不是对正向 end() 手动减一 —— std::map 迭代器不是随机访问类型,--m.end() 虽然可行但依赖实现细节,且易出错。
-
rbegin()指向最大元素,rend()指向“最小元素前一个位置”(即逻辑上的 begin 前) - 反向迭代器的
->first和->second用法和正向一致 - 不要混用正向和反向迭代器比较(如
it != m.rend()),类型不兼容
for (auto rit = m.rbegin(); rit != m.rend(); ++rit) {
std::cout first <p>真正容易被忽略的是迭代器失效边界:<code>insert</code> 不会使现有迭代器失效(<code>std::map</code> 特性),但 <code>erase</code> 会;另外所有方法里,key 都不可通过迭代器修改 —— 这不是语法限制,而是 map 红黑树结构决定的底层约束。</p>
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










