在C++的标准模板库STL中,map是一种键值对形式的关联容器,底层基于红黑树实现,默认会按照键的大小进行升序排序。实际开发中经常需要遍历map中的所有键,或者通过迭代器获取对应的键值对数据,下面介绍几种常用的实现方法。

正向迭代器遍历获取键值对
map的迭代器指向的是容器中的每个键值对元素,每个元素是一个pair<const key_type, mapped_type>类型的对象,其中first成员是键,second成员是对应的值。使用正向迭代器从begin遍历到end就可以获取所有键值对。
#include <iostream>
#include <map>
#include <string>
int main() {
// 创建并初始化map
std::map<int, std::string> studentMap;
studentMap[1] = "张三";
studentMap[2] = "李四";
studentMap[3] = "王五";
// 正向迭代器遍历
std::map<int, std::string>::iterator it;
for (it = studentMap.begin(); it != studentMap.end(); ++it) {
// 获取键
int key = it->first;
// 获取值
std::string value = it->second;
std::cout << "键: " << key << ", 值: " << value << std::endl;
}
return 0;
}
反向迭代器遍历
如果需要按照键的降序遍历map,可以使用反向迭代器,反向迭代器的begin对应原map的最后一个元素,end对应第一个元素的前一个位置。
#include <iostream>
#include <map>
#include <string>
int main() {
std::map<int, std::string> studentMap;
studentMap[1] = "张三";
studentMap[2] = "李四";
studentMap[3] = "王五";
// 反向迭代器遍历
std::map<int, std::string>::reverse_iterator rit;
for (rit = studentMap.rbegin(); rit != studentMap.rend(); ++rit) {
std::cout << "键: " << rit->first << ", 值: " << rit->second << std::endl;
}
return 0;
}
C++11之后的范围for遍历
C++11引入了范围for语法,可以简化遍历的写法,同样可以获取每个键值对的键和值,这种方式不需要显式声明迭代器,代码更简洁。
#include <iostream>
#include <map>
#include <string>
int main() {
std::map<int, std::string> studentMap;
studentMap[1] = "张三";
studentMap[2] = "李四";
studentMap[3] = "王五";
// 范围for遍历
for (auto& kv : studentMap) {
std::cout << "键: " << kv.first << ", 值: " << kv.second << std::endl;
}
return 0;
}
单独遍历map的所有键
如果只需要获取map中的所有键,不需要对应的值,可以在遍历时只取迭代器的first成员,或者将键存入到vector等容器中后续使用。
#include <iostream>
#include <map>
#include <string>
#include <vector>
int main() {
std::map<int, std::string> studentMap;
studentMap[1] = "张三";
studentMap[2] = "李四";
studentMap[3] = "王五";
// 遍历并收集所有键
std::vector<int> keys;
for (auto& kv : studentMap) {
keys.push_back(kv.first);
// 直接输出键
std::cout << "当前键: " << kv.first << std::endl;
}
std::cout << "所有键数量: " << keys.size() << std::endl;
return 0;
}
注意事项
- map的键是const类型,通过迭代器遍历时不能修改键的值,否则会破坏红黑树的结构,导致未定义行为。
- 如果只需要遍历值不需要键,可以直接使用迭代器的second成员,避免不必要的键操作。
- 范围for遍历时如果使用值传递,会拷贝整个pair对象,建议使用引用传递提升性能。
- 遍历过程中不要随意插入或删除元素,可能会导致迭代器失效,如果需要修改容器,建议先记录要操作的键,遍历结束后再处理。