You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 07:15:04