C++(STL):36---关联式容器multiset、multimap源码剖析

一、multiset

  • multiset的特性以及用法和set完全相同,唯一的差别在于它允许键值重复,因此它的插入操作采用的是底层RB-tree的insert_equal()而非insert_unique()

  •   

multiset源码

//以下代码摘录于stl_multiset.htemplate <class _Key, class _Compare, class _Alloc>class multiset {// requirements:

__STL_CLASS_REQUIRES(_Key, _Assignable);__STL_CLASS_BINARY_FUNCTION_CHECK(_Compare, bool, _Key, _Key);

public:

// typedefs:

typedef _Key     key_type;typedef _Key     value_type;typedef _Compare key_compare;typedef _Compare value_compare;private:typedef _Rb_tree<key_type, value_type,_Identity<value_type>, key_compare, _Alloc> _Rep_type;_Rep_type _M_t;  // red-black tree representing multisetpublic:typedef typename _Rep_type::const_pointer pointer;typedef typename _Rep_type::const_pointer const_pointer;typedef typename _Rep_type::const_reference reference;typedef typename _Rep_type::const_reference const_reference;typedef typename _Rep_type::const_iterator iterator;typedef typename _Rep_type::const_iterator const_iterator;typedef typename _Rep_type::const_reverse_iterator reverse_iterator;typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator;typedef typename _Rep_type::size_type size_type;typedef typename _Rep_type::difference_type difference_type;typedef typename _Rep_type::allocator_type allocator_type;

// allocation/deallocation

multiset() : _M_t(_Compare(), allocator_type()) {}explicit multiset(const _Compare& __comp,const allocator_type& __a = allocator_type()): _M_t(__comp, __a) {}

#ifdef __STL_MEMBER_TEMPLATES

template <class _InputIterator>multiset(_InputIterator __first, _InputIterator __last): _M_t(_Compare(), allocator_type()){ _M_t.insert_equal(__first, __last); }

template <class _InputIterator>multiset(_InputIterator __first, _InputIterator __last,const _Compare& __comp,const allocator_type& __a = allocator_type()): _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); }

#else

multiset(const value_type* __first, const value_type* __last): _M_t(_Compare(), allocator_type()){ _M_t.insert_equal(__first, __last); }

multiset(const value_type* __first, const value_type* __last,const _Compare& __comp,const allocator_type& __a = allocator_type()): _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); }

multiset(const_iterator __first, const_iterator __last): _M_t(_Compare(), allocator_type()){ _M_t.insert_equal(__first, __last); }

multiset(const_iterator __first, const_iterator __last,const _Compare& __comp,const allocator_type& __a = allocator_type()): _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); }

#endif /* __STL_MEMBER_TEMPLATES */

multiset(const multiset<_Key,_Compare,_Alloc>& __x) : _M_t(__x._M_t) {}multiset<_Key,_Compare,_Alloc>&operator=(const multiset<_Key,_Compare,_Alloc>& __x) {_M_t = __x._M_t;return *this;}

// accessors:

key_compare key_comp() const { return _M_t.key_comp(); }value_compare value_comp() const { return _M_t.key_comp(); }allocator_type get_allocator() const { return _M_t.get_allocator(); }

iterator begin() const { return _M_t.begin(); }iterator end() const { return _M_t.end(); }reverse_iterator rbegin() const { return _M_t.rbegin(); }reverse_iterator rend() const { return _M_t.rend(); }bool empty() const { return _M_t.empty(); }size_type size() const { return _M_t.size(); }size_type max_size() const { return _M_t.max_size(); }void swap(multiset<_Key,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); }

// insert/eraseiterator insert(const value_type& __x) {return _M_t.insert_equal(__x);}iterator insert(iterator __position, const value_type& __x) {typedef typename _Rep_type::iterator _Rep_iterator;return _M_t.insert_equal((_Rep_iterator&)__position, __x);}

#ifdef __STL_MEMBER_TEMPLATEStemplate <class _InputIterator>void insert(_InputIterator __first, _InputIterator __last) {_M_t.insert_equal(__first, __last);}#elsevoid insert(const value_type* __first, const value_type* __last) {_M_t.insert_equal(__first, __last);}void insert(const_iterator __first, const_iterator __last) {_M_t.insert_equal(__first, __last);}#endif /* __STL_MEMBER_TEMPLATES */void erase(iterator __position) {typedef typename _Rep_type::iterator _Rep_iterator;_M_t.erase((_Rep_iterator&)__position);}size_type erase(const key_type& __x) {return _M_t.erase(__x);}void erase(iterator __first, iterator __last) {typedef typename _Rep_type::iterator _Rep_iterator;_M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last);}void clear() { _M_t.clear(); }

// multiset operations:

iterator find(const key_type& __x) const { return _M_t.find(__x); }size_type count(const key_type& __x) const { return _M_t.count(__x); }iterator lower_bound(const key_type& __x) const {return _M_t.lower_bound(__x);}iterator upper_bound(const key_type& __x) const {return _M_t.upper_bound(__x);}pair<iterator,iterator> equal_range(const key_type& __x) const {return _M_t.equal_range(__x);}

#ifdef __STL_TEMPLATE_FRIENDStemplate <class _K1, class _C1, class _A1>friend bool operator== (const multiset<_K1,_C1,_A1>&,const multiset<_K1,_C1,_A1>&);template <class _K1, class _C1, class _A1>friend bool operator< (const multiset<_K1,_C1,_A1>&,const multiset<_K1,_C1,_A1>&);#else /* __STL_TEMPLATE_FRIENDS */friend bool __STD_QUALIFIERoperator== __STL_NULL_TMPL_ARGS (const multiset&, const multiset&);friend bool __STD_QUALIFIERoperator< __STL_NULL_TMPL_ARGS (const multiset&, const multiset&);#endif /* __STL_TEMPLATE_FRIENDS */};

二、multimap

  • multimap的特性以及用法和map完全相同,唯一的差别在于它允许键值重复,因此它的插入操作采用的是底层RB-tree的insert_equal()而非insert_unique()

  • multimap 

multimap源码

//下面代码摘录于stl_multimap.htemplate <class _Key, class _Tp, class _Compare, class _Alloc>class multimap {// requirements:

__STL_CLASS_REQUIRES(_Tp, _Assignable);__STL_CLASS_BINARY_FUNCTION_CHECK(_Compare, bool, _Key, _Key);

public:

// typedefs:

typedef _Key                  key_type;typedef _Tp                   data_type;typedef _Tp                   mapped_type;typedef pair<const _Key, _Tp> value_type;typedef _Compare              key_compare;

class value_compare : public binary_function<value_type, value_type, bool> {friend class multimap<_Key,_Tp,_Compare,_Alloc>;protected:_Compare comp;value_compare(_Compare __c) : comp(__c) {}public:bool operator()(const value_type& __x, const value_type& __y) const {return comp(__x.first, __y.first);}};

private:typedef _Rb_tree<key_type, value_type,_Select1st<value_type>, key_compare, _Alloc> _Rep_type;_Rep_type _M_t;  // red-black tree representing multimappublic:typedef typename _Rep_type::pointer pointer;typedef typename _Rep_type::const_pointer const_pointer;typedef typename _Rep_type::reference reference;typedef typename _Rep_type::const_reference const_reference;typedef typename _Rep_type::iterator iterator;typedef typename _Rep_type::const_iterator const_iterator;typedef typename _Rep_type::reverse_iterator reverse_iterator;typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator;typedef typename _Rep_type::size_type size_type;typedef typename _Rep_type::difference_type difference_type;typedef typename _Rep_type::allocator_type allocator_type;

// allocation/deallocation

multimap() : _M_t(_Compare(), allocator_type()) { }explicit multimap(const _Compare& __comp,const allocator_type& __a = allocator_type()): _M_t(__comp, __a) { }

#ifdef __STL_MEMBER_TEMPLATEStemplate <class _InputIterator>multimap(_InputIterator __first, _InputIterator __last): _M_t(_Compare(), allocator_type()){ _M_t.insert_equal(__first, __last); }

template <class _InputIterator>multimap(_InputIterator __first, _InputIterator __last,const _Compare& __comp,const allocator_type& __a = allocator_type()): _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); }#elsemultimap(const value_type* __first, const value_type* __last): _M_t(_Compare(), allocator_type()){ _M_t.insert_equal(__first, __last); }multimap(const value_type* __first, const value_type* __last,const _Compare& __comp,const allocator_type& __a = allocator_type()): _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); }

multimap(const_iterator __first, const_iterator __last): _M_t(_Compare(), allocator_type()){ _M_t.insert_equal(__first, __last); }multimap(const_iterator __first, const_iterator __last,const _Compare& __comp,const allocator_type& __a = allocator_type()): _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); }#endif /* __STL_MEMBER_TEMPLATES */

multimap(const multimap<_Key,_Tp,_Compare,_Alloc>& __x) : _M_t(__x._M_t) { }multimap<_Key,_Tp,_Compare,_Alloc>&operator=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x) {_M_t = __x._M_t;return *this;}

// accessors:

key_compare key_comp() const { return _M_t.key_comp(); }value_compare value_comp() const { return value_compare(_M_t.key_comp()); }allocator_type get_allocator() const { return _M_t.get_allocator(); }

iterator begin() { return _M_t.begin(); }const_iterator begin() const { return _M_t.begin(); }iterator end() { return _M_t.end(); }const_iterator end() const { return _M_t.end(); }reverse_iterator rbegin() { return _M_t.rbegin(); }const_reverse_iterator rbegin() const { return _M_t.rbegin(); }reverse_iterator rend() { return _M_t.rend(); }const_reverse_iterator rend() const { return _M_t.rend(); }bool empty() const { return _M_t.empty(); }size_type size() const { return _M_t.size(); }size_type max_size() const { return _M_t.max_size(); }void swap(multimap<_Key,_Tp,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); }

// insert/erase

iterator insert(const value_type& __x) { return _M_t.insert_equal(__x); }iterator insert(iterator __position, const value_type& __x) {return _M_t.insert_equal(__position, __x);}#ifdef __STL_MEMBER_TEMPLATEStemplate <class _InputIterator>void insert(_InputIterator __first, _InputIterator __last) {_M_t.insert_equal(__first, __last);}#elsevoid insert(const value_type* __first, const value_type* __last) {_M_t.insert_equal(__first, __last);}void insert(const_iterator __first, const_iterator __last) {_M_t.insert_equal(__first, __last);}#endif /* __STL_MEMBER_TEMPLATES */void erase(iterator __position) { _M_t.erase(__position); }size_type erase(const key_type& __x) { return _M_t.erase(__x); }void erase(iterator __first, iterator __last){ _M_t.erase(__first, __last); }void clear() { _M_t.clear(); }

// multimap operations:

iterator find(const key_type& __x) { return _M_t.find(__x); }const_iterator find(const key_type& __x) const { return _M_t.find(__x); }size_type count(const key_type& __x) const { return _M_t.count(__x); }iterator lower_bound(const key_type& __x) {return _M_t.lower_bound(__x); }const_iterator lower_bound(const key_type& __x) const {return _M_t.lower_bound(__x);}iterator upper_bound(const key_type& __x) {return _M_t.upper_bound(__x); }const_iterator upper_bound(const key_type& __x) const {return _M_t.upper_bound(__x);}pair<iterator,iterator> equal_range(const key_type& __x) {return _M_t.equal_range(__x);}pair<const_iterator,const_iterator> equal_range(const key_type& __x) const {return _M_t.equal_range(__x);}

#ifdef __STL_TEMPLATE_FRIENDStemplate <class _K1, class _T1, class _C1, class _A1>friend bool operator== (const multimap<_K1, _T1, _C1, _A1>&,const multimap<_K1, _T1, _C1, _A1>&);template <class _K1, class _T1, class _C1, class _A1>friend bool operator< (const multimap<_K1, _T1, _C1, _A1>&,const multimap<_K1, _T1, _C1, _A1>&);#else /* __STL_TEMPLATE_FRIENDS */friend bool __STD_QUALIFIERoperator== __STL_NULL_TMPL_ARGS (const multimap&, const multimap&);friend bool __STD_QUALIFIERoperator< __STL_NULL_TMPL_ARGS (const multimap&, const multimap&);#endif /* __STL_TEMPLATE_FRIENDS */};
相关推荐
实付 39.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值