将unordered_map作为另一个unordered_map的值时的赋值问题求助
解决嵌套unordered_map的插入异常问题
首先,我们来定位你遇到的核心问题:你使用了unordered_map::at()方法访问内层map的元素,但这个方法的特性是当指定的键不存在时,会直接抛出std::out_of_range异常——这正是你看到报错的原因。而你想要的是「如果键不存在就自动创建,再完成赋值」,这时候operator[]才是更合适的选择。
方案1:基于你现有指针结构的修改
你的内层map是指针类型,需要先解引用指针,再使用operator[]来自动创建不存在的键:
// 修正字符串数组的初始化错误 std::string postCodeSource[] = {"1111", "2222", "3333", "4444"}; std::unordered_map<std::string, std::unordered_map<int, Foo*>*> data; int k1 = 1234; for(int i = 0; i < 4; i++){ std::string postCode = postCodeSource[i]; // 用nullptr代替NULL更符合C++规范 if(data[postCode] == nullptr) { data[postCode] = new std::unordered_map<int, Foo*>(); } // 替换at()为operator[],自动创建不存在的键并赋值 (*data[postCode])[k1] = new Foo(postCodeSource[i]); }
(*data[postCode])[k1]会先检查内层map中是否存在键k1:如果不存在,就自动插入该键并将值默认初始化为nullptr,之后你再把新创建的Foo对象指针赋值给它,完全不会触发异常。
方案2:移除裸指针,简化嵌套结构(更推荐)
你当前用裸指针管理内层map,不仅容易引发内存泄漏,还增加了代码复杂度。建议直接把内层map作为外层map的直接值,而非指针:
std::string postCodeSource[] = {"1111", "2222", "3333", "4444"}; // 外层map的值直接是内层map,无需指针 std::unordered_map<std::string, std::unordered_map<int, Foo*>> data; int k1 = 1234; for(int i = 0; i < 4; i++){ std::string postCode = postCodeSource[i]; // 无需手动创建内层map,operator[]会自动构造空的内层map data[postCode][k1] = new Foo(postCodeSource[i]); }
这种写法会自动处理内层map的初始化:当postCode第一次出现时,data[postCode]会自动构造一个空的std::unordered_map<int, Foo*>,之后你直接通过[k1]插入新的键值对即可,代码简洁且更安全。
额外建议:避免裸指针,使用智能指针
如果你担心Foo*的内存泄漏问题,可以改用std::unique_ptr<Foo>来管理对象:
#include <memory> // 引入智能指针头文件 std::unordered_map<std::string, std::unordered_map<int, std::unique_ptr<Foo>>> data; // 插入时的写法 data[postCode][k1] = std::make_unique<Foo>(postCodeSource[i]);
这样不需要手动delete对象,智能指针会自动管理内存,彻底避免内存泄漏风险。
修正你代码中的小错误
你原来的字符串数组初始化存在语法错误:
// 错误写法:整数不能直接初始化std::string,数组声明方式也有误 std::string[] postCodeSource = new std::string{1111,2222,3333,4444}; // 正确写法 std::string postCodeSource[] = {"1111", "2222", "3333", "4444"};
内容的提问来源于stack exchange,提问作者alovaros
相关产品推荐
相关产品推荐

