跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

C++ STL 库:unordered_map 与 unordered_set 底层剖析

unordered_map 和 unordered_set 基于哈希表实现。分析其基本结构,指出两者共用 HashTable 模板类型,区别在于 Key 的存储方式。详细解析了普通迭代器与 const 迭代器的实现逻辑,包括指针转换与遍历机制。同时说明了 insert 操作返回值及 operator[] 的使用细节,强调 key 不可变而 value 可变性的控制策略。

暗影行者发布于 2026/3/16更新于 2026/8/2547 浏览
C++ STL 库:unordered_map 与 unordered_set 底层剖析

1.unordered_map、unordered_set 的基本结构

🚩unordered_set:

template <class K, class V>
class unordered_set {
    struct SetKeyOfT {
        const K& operator()(const K& key) {
            return key;
        }
    };
public:
    typedef typename hash_bucket::HashTable<K, K, SetKeyOfT>::const_iterator iterator;
    typedef typename hash_bucket::HashTable<K, K, SetKeyOfT>::const_iterator const_iterator;
    const_iterator begin() const {
        return _ht.begin();
    }
    const_iterator end() const {
        return _ht.end();
    }
    pair<const_iterator, bool> insert(const K& key) {
        pair<typename hash_bucket::HashTable<K, K, SetKeyOfT>::iterator, bool> ret = _ht.Insert(key);
        return pair<const_iterator, bool>(ret.first, ret.second);
    }
private:
    hash_bucket::HashTable<K, K, SetKeyOfT> _ht;
};

🚩unordered_map:

template <class K, class V>
class unordered_map {
    struct MapKeyOfT {
        const K& operator()(const pair<const K, V>& kv) {
            return kv.first;
        }
    };
public:
    typedef typename hash_bucket::HashTable<K, pair<const K, V>, MapKeyOfT>::iterator iterator;
    typedef typename hash_bucket::HashTable<K, pair<const K, V>, MapKeyOfT>::const_iterator const_iterator;
    iterator begin() {
        return _ht.begin();
    }
    iterator end() {
        return _ht.end();
    }
    const_iterator begin() const {
        return _ht.begin();
    }
    const_iterator end() const {
        return _ht.end();
    }
    pair<iterator, bool> insert(const pair<K, V>& kv) {
        return _ht.Insert(kv);
    }
    V& operator[](const K& key) {
        pair<iterator, bool> ret = _ht.Insert(make_pair(key, V()));
        return ret.first->second;
    }
private:
    hash_bucket::HashTable<K, pair<const K, V>, MapKeyOfT> _ht;
};

unordered_set 虽然是 k-k 类型,unordered_map 是 k-v 类型,但是实际上这两个类共用一个哈希表,准确来说是共用同一个模板类型,unordered_set 是 <K,K>,unordered_map 是 <K,pair<K,V>>。

2.普通迭代器

template <class K, class T, class Ptr, class Ref, class KeyOfT, class HashFunc>
struct HTIterator {
    typedef HashNode<T> Node;
    typedef HTIterator<K, T, Ptr, Ref, KeyOfT, HashFunc> Self;
    typedef HTIterator<K, T, T*, T&, KeyOfT, HashFunc> Iterator;
    Node* _node;
    const HashTable<K, T, KeyOfT, HashFunc>* _pht;

    /*HTIterator(Node* node, HashTable<K, T, KeyOfT, HashFunc>* pht) :_node(node) ,_pht(pht) {}*/
    HTIterator(Node* node, const HashTable<K, T, KeyOfT, HashFunc>* pht):_node(node),_pht(pht){}

    // 普通迭代器时,他是拷贝构造
    // const 迭代器时,他是构造
    // HTIterator(const Iterator& it):_node(it._node),_pht(it._pht){}

    Ref operator*() {
        return _node->_data;
    }
    Ptr operator->() {
        return &_node->_data;
    }
    Self& operator++() {
        if(_node->_next) { // 当前桶还没完
            _node = _node->_next;
        } else {
            KeyOfT kot;
            HashFunc hf;
            size_t hashi = hf(kot(_node->_data)) % _pht->_table.size(); // 从下一个位置查找查找下一个不为空的桶
            ++hashi;
            while(hashi < _pht->_table.size()) {
                if(_pht->_table[hashi]) {
                    _node = _pht->_table[hashi];
                    return *this;
                } else {
                    ++hashi;
                }
            }
            _node = nullptr;
        }
        return *this;
    }
    bool operator!=(const Self& s) {
        return _node != s._node;
    }
    bool operator==(const Self& s) {
        return _node == s._node;
    }
};

typedef HTIterator<K, T, T*, T&, KeyOfT, HashFunc> Iterator 和构造函数是为 Insert 操作准备的,因为涉及到普通迭代器创建 const 迭代器。

🔥值得注意的是: 有人说不是可以通过权限转化吗?但是权限转化是只有涉及引用和指针的类型时才会生效,而这里是模板参数之间的转化。

3.const 迭代器

unordered_set 本身无论是 const 迭代器还是普通迭代器都会被 typedef 为 const_iterator。

对于 unordered_map 来说,key 是不允许改变的,value 是可以改变的,但是如果像 set 那样写的话 key 和 value 都不能修改了,所以直接在 pair 的 key 加 const,控制 value 即可。

4.insert 返回值 operator[]

🚩unordered_set:

pair<const_iterator, bool> insert(const K& key) {
    //return _ht.Insert(key);
    pair<typename hash_bucket::HashTable<K, K, SetKeyOfT>::iterator, bool> ret = _ht.Insert(key);
    return pair<const_iterator, bool>(ret.first, ret.second);
}

🚩unordered_map:

pair<iterator, bool> insert(const pair<K, V>& kv) {
    return _ht.Insert(kv);
}
V& operator[](const K& key) {
    pair<iterator, bool> ret = _ht.Insert(make_pair(key, V()));
    return ret.first->second;
}

这里的转化尤为复杂,一定要看之前文章的详细解析。

目录

  1. 1.unorderedmap、unorderedset 的基本结构
  2. 2.普通迭代器
  3. 3.const 迭代器
  4. 4.insert 返回值 operator[]
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • KingbaseES 数据库智能 SQL 防护机制与实战配置
  • Visual C++ 运行库修复指南:解决 Windows 程序无法启动问题
  • C++ 基础:引用用法、inline 内联函数与 nullptr 详解
  • Proxy 与 Object.defineProperty 深度解析:JavaScript 拦截机制对比
  • ELF 解析:Linux 程序从编译到运行的全流程
  • Android Jetpack 架构组件详解与实战指南
  • Dify 工作流发布为 MCP Server 实战指南
  • Git 入门指南:从零理解版本控制与团队协作
  • MySQL 内置函数实战:日期、字符串与数学运算详解
  • RAG 检索增强生成技术概览
  • 使用 LLaMA-Factory 训练 LLM 大模型并用 Ollama 调用
  • C++ 高精度时间库 chrono 详解
  • 大模型时代:新手与程序员转型 AI 行业的最佳路径
  • 字节开源 DeerFlow 2.0:从深度研究到 Super Agent 基础设施
  • C++ STL 容器 vector 详解:定义、访问与操作
  • C++ 多态底层实现原理详解
  • 牛客 NC221681 dd 爱框框:滑动窗口解法详解
  • 利用 DeepSeek 辅助开发贪吃蛇游戏
  • 自然语言处理在教育领域的应用与实战
  • Byte Pair Encoding (BPE) 分词算法详解与代码实现

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online