如何通过键获取std::map节点的引用
获取std::map整个节点的引用
你说得对,std::map::operator[]确实只会返回值部分(value_type&)的引用,而且如果键不存在的话还会自动插入一个默认构造的元素。要拿到整个节点(也就是std::pair<const key_type, value_type>&,注意这里key是const的——map里的键不能被修改)的引用,有几种不同的方案,取决于你的需求:
情况1:仅当键存在时获取节点引用
如果只需要在键已经存在的情况下拿到节点,用find()方法最稳妥——它不会像operator[]那样自动插入新元素:
#include <map> std::map<int, std::string> my_map = {{1, "one"}, {2, "two"}}; int target_key = 1; auto it = my_map.find(target_key); if (it != my_map.end()) { // 拿到整个节点的引用 std::pair<const int, std::string>& node = *it; // 可以访问node.first(const键)和node.second(值) node.second = "updated_one"; // 修改值是允许的 // node.first = 3; // 错误!map的键是const,不能修改 }
情况2:键不存在时插入,同时获取节点引用
如果希望键不存在时自动插入,之后拿到整个节点的引用,有几种方式:
方式A:先确保元素存在,再find
先用operator[]触发插入(如果需要),再用find()拿到迭代器:
std::map<int, std::string> my_map; int target_key = 3; // 如果key不存在,会插入一个默认构造的std::string my_map[target_key]; auto it = my_map.find(target_key); std::pair<const int, std::string>& node = *it; node.second = "three"; // 给默认值赋值
方式B:用emplace(C++11及以上)
emplace()可以直接构造元素,返回的pair里包含迭代器和一个bool值(表示是否是新插入的元素):
std::map<int, std::string> my_map; int target_key = 3; // 直接构造元素,返回的it指向插入或已存在的节点 auto [it, inserted] = my_map.emplace(target_key, "three"); std::pair<const int, std::string>& node = *it; if (inserted) { // 说明是新插入的节点 } else { // 说明key已经存在,node是已有的节点 }
方式C:用insert_or_assign(C++17及以上)
如果需要不管键是否存在都赋值,insert_or_assign很方便:
std::map<int, std::string> my_map = {{3, "old_three"}}; int target_key = 3; auto [it, inserted] = my_map.insert_or_assign(target_key, "new_three"); std::pair<const int, std::string>& node = *it; // inserted为true表示是新插入,false表示覆盖了已有值
重要提醒
map中的节点类型是std::pair<const key_type, value_type>,而不是你最初写的std::pair<key_type, value_type>——因为map的键是不可修改的,所以必须加上const修饰key类型,否则会出现编译错误。
内容的提问来源于stack exchange,提问作者Harry
相关产品推荐
相关产品推荐

