为何传入函数的const引用unordered_map无法用[]取键值,本地实例却可以?
关于const引用std::unordered_map无法使用[]运算符的问题
嘿,这个问题的核心其实和std::unordered_map里operator[]的设计逻辑直接相关,我来给你掰扯清楚:
为什么const引用的map不能用[]?
std::unordered_map的operator[]有一个关键特性:当你传入的键不存在于map中时,它会自动插入一个默认构造的键值对到容器里。这个操作会修改map的内容,而你的函数参数是const std::unordered_map<...>&——const意味着这个map是只读的,不允许任何修改操作。
因为operator[]本身不是const成员函数(它会修改容器),所以编译器会直接报错,禁止你在const引用的map上调用它。
为什么本地普通map可以用[]?
你本地定义的非const std::unordered_map没有只读限制,调用operator[]时哪怕插入新元素也属于合法的修改操作,所以编译器不会拦着你。
你的代码该怎么改?
你已经用find()检查了CAPABILITY_TYPE_SPECIE这个键是否存在,这里有两种安全的替代方案:
方案1:使用at()成员函数
at()是const成员函数,它会在键存在时返回对应值的引用,不会修改容器。如果键不存在(虽然你已经检查过了,但以防万一),它会抛出std::out_of_range异常:
GameObject(const std::unordered_map<int,std::unordered_map<int,int>>& objectParameters){ if (objectParameters.find(CAPABILITY_TYPE_SPECIE)!=objectParameters.end()) { auto map2 = objectParameters.at(CAPABILITY_TYPE_SPECIE); // 后续操作... } }
方案2:直接使用find()返回的迭代器
既然已经调用了find(),可以直接用迭代器访问对应的值,避免额外的查找操作:
GameObject(const std::unordered_map<int,std::unordered_map<int,int>>& objectParameters){ auto it = objectParameters.find(CAPABILITY_TYPE_SPECIE); if (it != objectParameters.end()) { auto map2 = it->second; // 后续操作... } }
总结一下
operator[]会修改容器(插入新元素),因此永远不能在const引用的std::unordered_map(或std::map)上使用- 对于const容器,优先用
at()(需要确保键存在)或者find()+迭代器的方式访问元素
内容的提问来源于stack exchange,提问作者Rahul Iyer
相关产品推荐
相关产品推荐

