SGISTL源码探究-关联式容器:hash_multimap
来源:互联网 发布:ep软件 编辑:程序博客网 时间:2024/06/01 09:03
前言
本小节将介绍hash_multimap
的源码实现,它与hash_map
的不同与map
和multimap
的不同类似,所以我们可以一边分析它们的不同之处,一边顺便复习hash_map
。
hash_multimap
的实现
定义及数据结构
#ifndef __STL_LIMITED_DEFAULT_TEMPLATEStemplate <class Key, class T, class HashFcn = hash<Key>, class EqualKey = equal_to<Key>, class Alloc = alloc>#elsetemplate <class Key, class T, class HashFcn, class EqualKey, class Alloc = alloc>#endifclass hash_multimap{private: //这里不要忽视了pair的第一个元素是const型的,不允许修改 typedef hashtable<pair<const Key, T>, Key, HashFcn, select1st<pair<const Key, T> >, EqualKey, Alloc> ht; ht rep;public: //一些别名 typedef typename ht::key_type key_type; typedef T data_type; typedef T mapped_type; typedef typename ht::value_type value_type; typedef typename ht::hasher hasher; typedef typename ht::key_equal key_equal; typedef typename ht::size_type size_type; typedef typename ht::difference_type difference_type; typedef typename ht::pointer pointer; typedef typename ht::const_pointer const_pointer; typedef typename ht::reference reference; typedef typename ht::const_reference const_reference; typedef typename ht::iterator iterator; typedef typename ht::const_iterator const_iterator; hasher hash_funct() const { return rep.hash_funct(); } key_equal key_eq() const { return rep.key_eq(); }
构造函数
public: /* 构造函数 指定大小、哈希函数、比较key大小的函数 */ hash_multimap() : rep(100, hasher(), key_equal()) {} explicit hash_multimap(size_type n) : rep(n, hasher(), key_equal()) {} hash_multimap(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {} hash_multimap(size_type n, const hasher& hf, const key_equal& eql) : rep(n, hf, eql) {} //插入元素时使用的insert_equal#ifdef __STL_MEMBER_TEMPLATES template <class InputIterator> hash_multimap(InputIterator f, InputIterator l) : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); } template <class InputIterator> hash_multimap(InputIterator f, InputIterator l, size_type n) : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); } template <class InputIterator> hash_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf) : rep(n, hf, key_equal()) { rep.insert_equal(f, l); } template <class InputIterator> hash_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf, const key_equal& eql) : rep(n, hf, eql) { rep.insert_equal(f, l); }#else hash_multimap(const value_type* f, const value_type* l) : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); } hash_multimap(const value_type* f, const value_type* l, size_type n) : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); } hash_multimap(const value_type* f, const value_type* l, size_type n, const hasher& hf) : rep(n, hf, key_equal()) { rep.insert_equal(f, l); } hash_multimap(const value_type* f, const value_type* l, size_type n, const hasher& hf, const key_equal& eql) : rep(n, hf, eql) { rep.insert_equal(f, l); } hash_multimap(const_iterator f, const_iterator l) : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); } hash_multimap(const_iterator f, const_iterator l, size_type n) : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); } hash_multimap(const_iterator f, const_iterator l, size_type n, const hasher& hf) : rep(n, hf, key_equal()) { rep.insert_equal(f, l); } hash_multimap(const_iterator f, const_iterator l, size_type n, const hasher& hf, const key_equal& eql) : rep(n, hf, eql) { rep.insert_equal(f, l); }#endif /*__STL_MEMBER_TEMPLATES */
常用操作
public: //这部分都与hash_map相同 size_type size() const { return rep.size(); } size_type max_size() const { return rep.max_size(); } bool empty() const { return rep.empty(); } void swap(hash_multimap& hs) { rep.swap(hs.rep); } friend bool operator== __STL_NULL_TMPL_ARGS (const hash_multimap&, const hash_multimap&); //返回首/尾迭代器,尾迭代器为指向null的节点的指针,首迭代器为指向第一个bucket不为空的头节点的指针 iterator begin() { return rep.begin(); } iterator end() { return rep.end(); } const_iterator begin() const { return rep.begin(); } const_iterator end() const { return rep.end(); }public: //插入操作,调用的是insert_equal iterator insert(const value_type& obj) { return rep.insert_equal(obj); }#ifdef __STL_MEMBER_TEMPLATES template <class InputIterator> void insert(InputIterator f, InputIterator l) { rep.insert_equal(f,l); }#else void insert(const value_type* f, const value_type* l) { rep.insert_equal(f,l); } void insert(const_iterator f, const_iterator l) { rep.insert_equal(f, l); }#endif /*__STL_MEMBER_TEMPLATES */ iterator insert_noresize(const value_type& obj) { return rep.insert_equal_noresize(obj); } iterator find(const key_type& key) { return rep.find(key); } const_iterator find(const key_type& key) const { return rep.find(key); } /* 在hash_map中,这里实现了对[]操作符的重载 * 但是在hash_multimap中没有对其重载 * 是因为key可以重复,那么下标访问时可能就对应了多个元素,此时该返回哪个就成了难题 */ size_type count(const key_type& key) const { return rep.count(key); } pair<iterator, iterator> equal_range(const key_type& key) { return rep.equal_range(key); } pair<const_iterator, const_iterator> equal_range(const key_type& key) const { return rep.equal_range(key); } //删除操作 size_type erase(const key_type& key) {return rep.erase(key); } void erase(iterator it) { rep.erase(it); } void erase(iterator f, iterator l) { rep.erase(f, l); } void clear() { rep.clear(); }public: /* 剩下的部分都与hash_map相同了 */ void resize(size_type hint) { rep.resize(hint); } size_type bucket_count() const { return rep.bucket_count(); } size_type max_bucket_count() const { return rep.max_bucket_count(); } size_type elems_in_bucket(size_type n) const { return rep.elems_in_bucket(n); }};template <class Key, class T, class HF, class EqKey, class Alloc>inline bool operator==(const hash_multimap<Key, T, HF, EqKey, Alloc>& hm1, const hash_multimap<Key, T, HF, EqKey, Alloc>& hm2){ return hm1.rep == hm2.rep;}#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDERtemplate <class Key, class T, class HashFcn, class EqualKey, class Alloc>inline void swap(hash_multimap<Key, T, HashFcn, EqualKey, Alloc>& hm1, hash_multimap<Key, T, HashFcn, EqualKey, Alloc>& hm2){ hm1.swap(hm2);}#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
小结
本小节对hash_multimap
进行了分析。它和hash_map
的不同之处除了插入元素时允许重复之外,hash_multimap
还不支持下标运算。
关联式容器部分就到此为止了,其实只要把hashtable
的实现搞明白了,对hash_set
和hash_map
之类的理解就轻松多了。
在下一小节中,我们将对STL
中的泛型算法部分开始分析,在具体的源码分析中,我不会列出所有的算法,而是选择其中比较经典和常用的算法进行分析。
阅读全文
0 0
- SGISTL源码探究-关联式容器:hash_multimap
- SGISTL源码探究-关联式容器:set
- SGISTL源码探究-关联式容器:map
- SGISTL源码探究-关联式容器:multiset
- SGISTL源码探究-关联式容器:multimap
- SGISTL源码探究-关联式容器:hash_set
- SGISTL源码探究-关联式容器:hash_map
- SGISTL源码探究-关联式容器:hash_multiset
- STL源码剖析 - 第5章 关联式容器 - hash_multimap
- SGISTL源码探究-vector容器(上)
- SGISTL源码探究-vector容器(下)
- SGISTL源码探究-list容器(上)
- SGISTL源码探究-list容器(下)
- SGISTL源码探究-deque容器(上)
- SGISTL源码探究-deque容器(下)
- SGISTL源码探究-配接器
- 【STL源码剖析读书笔记】【第5章】关联式容器之hash_set、hash_map、hash_multiset和hash_multimap
- STL源码剖析-关联式容器之hash_set、hash_map、hash_multiset和hash_multimap
- 测试模型之W模型
- 【错误】关于DateTable中 Cannot reinitialise DataTable问题
- 设计模式学习-简单工厂模式
- 编译
- python Tkinter学习
- SGISTL源码探究-关联式容器:hash_multimap
- elasticsearch 5.1 java开发用例
- xcode8 如何安装插件
- Hibernate批量保存前台传递的EasyUI-datagrid数据
- jquery 解析json
- USB通信协议——错误检查
- Java线程(四):线程中断、线程让步、线程睡眠、线程合并
- echarts中datazoom相关配置
- springmvc结合base64存取图片到mysql