C++如何遍历map中的所有键值对?(迭代器用法)

推荐使用范围for循环遍历std::map键值对,简洁安全;需控制流程时用begin()/end()显式迭代器,注意键不可修改、遍历时禁插删元素。

用迭代器遍历 std::map 中的所有键值对,最常用且推荐的方式是使用范围 for 循环显式声明迭代器。两者底层都依赖 map::iterator(或 const_iterator),本质一致,但写法和适用场景略有不同。

方式一:范围 for 循环(推荐,简洁安全)

适用于只读访问或需要修改值(非键)的场景,代码清晰、不易出错:

std::map myMap = {{"apple", 1}, {"banana", 2}, {"cherry", 3}};

// 遍历所有键值对(自动推导类型)
for (const auto& pair : myMap) {
    std::cout << "Key: " << pair.first << ", Value: " << pair.second << '\n';
}

// 若需修改 value(注意:不能修改 first,因为 key 是 const 的)
for (auto& pair : myMap) {
    pair.second *= 10; // 合法:修改 value
    // pair.first = "new_key"; // 编译错误!key 不可修改
}

方式二:显式使用 begin()/end() 迭代器

适合需要控制遍历流程(如中途 break、条件跳过)、或兼容旧标准(C++11 之前)的场景

  • map::iterator 可读写 value,但 key 始终不可修改(因 map 按 key 排序,改 key 会破坏结构)
  • map::const_iterator 仅允许读取,更安全,尤其在函数参数中传递时
std::map m = {{1, "one"}, {2, "two"}, {3, "three"}};

// 使用普通迭代器(可修改 value)
for (auto it = m.begin(); it != m.end(); ++it) {
    std::cout << it->first << " -> " << it->second << '\n';
    it->second += "!"; // 修改 value 合法
}

// 使用 const_iterator(只读,更明确语义)
for (auto it = m.cbegin(); it != m.cend(); ++it) {
    std::cout << it->first << " -> " << it->second << '\n';
}

注意事项与常见误区

  • std::map 的迭代器是双向迭代器,支持 ++--,但不支持 += 或随机访问(如 it + 5
  • 遍历时不要在循环中插入或删除元素(除非用 erase() 返回的迭代器),否则会导致迭代器失效、未定义行为
  • 若需边遍历边删除满足条件的元素,用 it = m.erase(it)(C++11 起返回下一个有效迭代器)
  • 键类型必须支持 比较(默认为 std::less),这是 map 有序性的基础

补充:反向遍历

rbegin() / rend() 实现从大到小顺序访问:

for (auto rit = myMap.rbegin(); rit != myMap.rend(); ++rit) {
    std::cout << rit->first << " : " << rit->second << '\n';
}