C++14中如何向多层嵌套std::unordered_map插入std::unique_ptr
核心前提说明
std::unique_ptr是独占所有权的智能指针,没有提供拷贝构造、拷贝赋值函数,插入到容器时只能通过移动语义传递右值,或是直接原地构造实例。你使用的C++14刚好支持std::make_unique,可以很方便地创建unique_ptr实例。
为了简化代码书写,首先可以给嵌套map定义别名:
#include <unordered_map> #include <memory> // 假设MyStruct已经定义 struct MyStruct { // 你的结构定义 }; using NestedMap = std::unordered_map<uint64_t, std::unordered_map<uint64_t, std::unordered_map<uint64_t, std::unique_ptr<MyStruct>>>>;
常用插入方式
场景1:允许覆盖已有元素,不需要提前判断键是否存在
直接用operator[]访问嵌套层级,赋值时传递右值unique_ptr即可,写法最简洁:
NestedMap my_map; // 方式1:直接赋值临时unique_ptr(右值,自动移动) my_map[1001][2001][3001] = std::make_unique<MyStruct>(/* MyStruct的构造参数 */); // 方式2:移动左值unique_ptr auto ptr = std::make_unique<MyStruct>(); my_map[1001][2001][3002] = std::move(ptr); // 注意:移动后ptr变为空,不能再访问
如果对应层级的键不存在,operator[]会自动构造空的内层map,不需要手动处理嵌套层级的初始化。
场景2:不允许覆盖已有元素,避免生成多余的空内层map
如果不希望插入时覆盖已有值,也不希望因为访问不存在的键生成空的内层map,可以组合find和emplace实现安全插入:
uint64_t key1 = 1001, key2 = 2001, key3 = 3001; auto new_ptr = std::make_unique<MyStruct>(); // 查找第一层键 auto it1 = my_map.find(key1); if (it1 == my_map.end()) { it1 = my_map.emplace(key1, NestedMap::mapped_type{}).first; } // 查找第二层键 auto it2 = it1->second.find(key2); if (it2 == it1->second.end()) { it2 = it1->second.emplace(key2, NestedMap::mapped_type::mapped_type{}).first; } // 最内层插入,仅当key3不存在时插入 if (it2->second.find(key3) == it2->second.end()) { it2->second.emplace(key3, std::move(new_ptr)); }
常见错误示例
以下写法会编译失败,原因是尝试拷贝unique_ptr违反独占所有权规则:
std::unique_ptr<MyStruct> ptr = std::make_unique<MyStruct>(); my_map[1][2][3] = ptr; // 错误:unique_ptr不支持拷贝赋值
内容的提问来源于stack exchange,提问作者Martin G
相关产品推荐
相关产品推荐

