STL学习——set/map/multiset/mulitmap篇

STL学习——set/map/multiset/mulitmap篇

set

  • 简介

    set特性:所有元素都会根据元素的键值自动被排序。set的元素不想map那么,可以同时拥有实值(value)和键值(key),set元素的键值就是实值,实值就是键值。set中不允许两个元素具有相同的键值。

    因为set元素值就是键值,其关系到set元素的排列规则,如果任意改变set元素值,则会破坏set的组织,故不可以通过set迭代器来改变set的元素值。set迭代器其底层利用RB-tree实现。对于set的各种操作接口,Rb-tree也都提供,故几乎所有的set操作行为都只需转调用RB-tree操作即可。

    set与list具有某些相同性质:当客户端对它进行元素新增操作或删除操作时,操作之前的所有迭代器,在操作完之后依然有效。但被删除的那个元素的迭代器例外。

    set中的相关算法主要包括求交集,并集,差集,对称差集等。

  • 源码分析

    emplate <class _Key, class _Compare __STL_DEPENDENT_DEFAULT_TMPL(less<_Key>),   // 缺省情况下采用递增排序
              class _Alloc = __STL_DEFAULT_ALLOCATOR(_Key) >
    class set;
    
    template <class _Key, class _Compare, class _Alloc>
    inline bool operator==(const set<_Key,_Compare,_Alloc>& __x, 
                           const set<_Key,_Compare,_Alloc>& __y);
    
    template <class _Key, class _Compare, class _Alloc>
    inline bool operator<(const set<_Key,_Compare,_Alloc>& __x, 
                          const set<_Key,_Compare,_Alloc>& __y);
    
    
    template <class _Key, class _Compare, class _Alloc>
    class set {
      // 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;     // 此处key_compare和value_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 set         // 采用红黑树(Rb-tree)来表现set
    public:
      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
      // 注意,set一定使用Rb-tree的insert_unique()而非insert_equal()
      // multiset才使用Rb-tree的insert_equal()
      // 因为set不允许相同键值存在,multiset才允许相同键值存在
      set() : _M_t(_Compare(), allocator_type()) {}
      explicit set(const _Compare& __comp,
                   const allocator_type& __a = allocator_type())
        : _M_t(__comp, __a) {}
    
    #ifdef __STL_MEMBER_TEMPLATES
      // 构造函数
      template <class _InputIterator>
      set(_InputIterator __first, _InputIterator __last)
        : _M_t(_Compare(), allocator_type())
        { _M_t.insert_unique(__first, __last); }
    
      template <class _InputIterator>
      set(_InputIterator __first, _InputIterator __last, const _Compare& __comp,
          const allocator_type& __a = allocator_type())
        : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); }
    #else
      set(const value_type* __first, const value_type* __last) 
        : _M_t(_Compare(), allocator_type()) 
        { _M_t.insert_unique(__first, __last); }
    
      set(const value_type* __first, 
          const value_type* __last, const _Compare& __comp,
          const allocator_type& __a = allocator_type())
        : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); }
    
      set(const_iterator __first, const_iterator __last)
        : _M_t(_Compare(), allocator_type()) 
        { _M_t.insert_unique(__first, __last); }
    
      set(const_iterator __first, const_iterator __last, const _Compare& __comp,
          const allocator_type& __a = allocator_type())
        : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); }
    #endif /* __STL_MEMBER_TEMPLATES */
      // 赋值操作
      set(const set<_Key,_Compare,_Alloc>& __x) : _M_t(__x._M_t) {}
      set<_Key,_Compare,_Alloc>& operator=(const set<_Key, _Compare, _Alloc>& __x)
      { 
        _M_t = __x._M_t; 
        return *this;
      }
    
      // 以下所有的set操作行为,Rb-tree都已提供,set只要传递调用即可
      key_compare key_comp() const { return _M_t.key_comp(); }
      value_compare value_comp() const { return _M_t.key_comp(); }    // set的vaule_comp()事实上为Rb-tree的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(set<_Key,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); }
    
      // 插入与删除操作
      // 插入值
      pair<iterator,bool> insert(const value_type& __x) { 
        pair<typename _Rep_type::iterator, bool> __p = _M_t.insert_unique(__x); 
        return pair<iterator, bool>(__p.first, __p.second);
      }
      // 在某位置插入值
      iterator insert(iterator __position, const value_type& __x) {
        typedef typename _Rep_type::iterator _Rep_iterator;
        return _M_t.insert_unique((_Rep_iterator&)__position, __x);
      }
    #ifdef __STL_MEMBER_TEMPLATES
      // 多值插入
      template <class _InputIterator>
      void insert(_InputIterator __first, _InputIterator __last) {
        _M_t.insert_unique(__first, __last);
      }
    #else
      void insert(const_iterator __first, const_iterator __last) {
        _M_t.insert_unique(__first, __last);
      }
      void insert(const value_type* __first, const value_type* __last) {
        _M_t.insert_unique(__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(); }
    
      // set操作:
      // 查找
      iterator find(const key_type& __x) const { return _M_t.find(__x); }
      // 统计
      size_type count(const key_type& __x) const {
        return _M_t.find(__x) == _M_t.end() ? 0 : 1;
      }
      // 下边界
      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_FRIENDS
      template <class _K1, class _C1, class _A1>
      friend bool operator== (const set<_K1,_C1,_A1>&, const set<_K1,_C1,_A1>&);
      template <class _K1, class _C1, class _A1>
      friend bool operator< (const set<_K1,_C1,_A1>&, const set<_K1,_C1,_A1>&);
    #else /* __STL_TEMPLATE_FRIENDS */
      friend bool __STD_QUALIFIER
      operator== __STL_NULL_TMPL_ARGS (const set&, const set&);
      friend bool __STD_QUALIFIER
      operator<  __STL_NULL_TMPL_ARGS (const set&, const set&);
    #endif /* __STL_TEMPLATE_FRIENDS */
    };
    // ==操作符
    template <class _Key, class _Compare, class _Alloc>
    inline bool operator==(const set<_Key,_Compare,_Alloc>& __x, 
                           const set<_Key,_Compare,_Alloc>& __y) {
      return __x._M_t == __y._M_t;
    }
    // <操作符
    template <class _Key, class _Compare, class _Alloc>
    inline bool operator<(const set<_Key,_Compare,_Alloc>& __x, 
                          const set<_Key,_Compare,_Alloc>& __y) {
      return __x._M_t < __y._M_t;
    }
    

map

  • 简介

    map特性:所有元素都会根据元素的键值自动被排序。map的所有元素都是pair,同时拥有实值(value)和键值(key)。pair的第一元素被视为键值,第二元素被视为实值。map不允许两个元素具有相同的键值。

    不可以通过map迭代器改变map元素的键值,因为map元素的键值关系到map元素的排列规则,如果改变,会破坏map组织。但对于map中的实值,可以通过map迭代器改变,因为map元素的实值不影响map元素的排列规则。

    map与list具有某些相同性质:当客户端对它进行元素新增操作或删除操作时,操作之前的所有迭代器,在操作完之后依然有效。但被删除的那个元素的迭代器例外。map迭代器其底层利用RB-tree实现。对于set的各种操作接口,Rb-tree也都提供,故几乎所有的map操作行为都只需转调用RB-tree操作即可。

  • 源码分析

    template <class _Key, class _Tp, 
              class _Compare __STL_DEPENDENT_DEFAULT_TMPL(less<_Key>),       // 缺省采用递增排序
              class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) >
    class map;
    // ==运算符
    template <class _Key, class _Tp, class _Compare, class _Alloc>
    inline bool operator==(const map<_Key,_Tp,_Compare,_Alloc>& __x, 
                           const map<_Key,_Tp,_Compare,_Alloc>& __y);
    // <运算符
    template <class _Key, class _Tp, class _Compare, class _Alloc>
    inline bool operator<(const map<_Key,_Tp,_Compare,_Alloc>& __x, 
                          const map<_Key,_Tp,_Compare,_Alloc>& __y);
    // map类定义
    template <class _Key, class _Tp, class _Compare, class _Alloc>
    class map {
    public:
    
    // requirements:
    
      __STL_CLASS_REQUIRES(_Tp, _Assignable);
      __STL_CLASS_BINARY_FUNCTION_CHECK(_Compare, bool, _Key, _Key);
    
    // 定义:
      typedef _Key                  key_type;         // 键值型别
      typedef _Tp                   data_type;        // 数据(实值)型别
      typedef _Tp                   mapped_type;
      typedef pair<const _Key, _Tp> value_type;       // 元素型别(键值/实值)
      typedef _Compare              key_compare;      // 键值比较函数
      // 以下定义一个functor,其作用就是调用“元素比较函数” 
      class value_compare
        : public binary_function<value_type, value_type, bool> {
      friend class map<_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:
      // 以下定义表述型别。以map元素型别(一个pair)的第一型别,作为Rb-tree节点的键值型别
      typedef _Rb_tree<key_type, value_type, 
                       _Select1st<value_type>, key_compare, _Alloc> _Rep_type;
      _Rep_type _M_t;  // red-black tree representing map  // 以红黑树Rb-tree表现map
    public:
      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;       // 注意:map不像set一样将iterator定义为Rb-tree的const_iterator。因为它允许用户通过其迭代器修改元素的实值(value) 
      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
      // 分配/释放空间
      map() : _M_t(_Compare(), allocator_type()) {}
      explicit map(const _Compare& __comp,
                   const allocator_type& __a = allocator_type())
        : _M_t(__comp, __a) {}
    
      // 注意:map一定使用底层Rb-tree的insert_unique()而非insert_equal()
      // multimap才使用insert_equal()
      // 因为map不允许相同键值存在,multimap才允许相同键值存在
    #ifdef __STL_MEMBER_TEMPLATES
      // map构造函数
      template <class _InputIterator>
      map(_InputIterator __first, _InputIterator __last)
        : _M_t(_Compare(), allocator_type())
        { _M_t.insert_unique(__first, __last); }
    
      template <class _InputIterator>
      map(_InputIterator __first, _InputIterator __last, const _Compare& __comp,
          const allocator_type& __a = allocator_type())
        : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); }
    #else
      map(const value_type* __first, const value_type* __last)
        : _M_t(_Compare(), allocator_type())
        { _M_t.insert_unique(__first, __last); }
    
      map(const value_type* __first,
          const value_type* __last, const _Compare& __comp,
          const allocator_type& __a = allocator_type())
        : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); }
    
      map(const_iterator __first, const_iterator __last)
        : _M_t(_Compare(), allocator_type()) 
        { _M_t.insert_unique(__first, __last); }
    
      map(const_iterator __first, const_iterator __last, const _Compare& __comp,
          const allocator_type& __a = allocator_type())
        : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); }
    
    #endif /* __STL_MEMBER_TEMPLATES */
      // 赋值操作
      map(const map<_Key,_Tp,_Compare,_Alloc>& __x) : _M_t(__x._M_t) {}
      map<_Key,_Tp,_Compare,_Alloc>&
      operator=(const map<_Key, _Tp, _Compare, _Alloc>& __x)
      {
        _M_t = __x._M_t;
        return *this; 
      }
    
      // accessors:
      // 以下所有的map操作行为,Rb-tree都已提供,map只要转调用即可
      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(); }
      // 注意以下 下标(subscirpt)操作符,用法两种,可能作为左值运用(内容可以被修改),也可能作为右值运用(内容不可被改变)
      // subscript工作,都是先根据键值找出其实值,再做打算。
      _Tp& operator[](const key_type& __k) {
        iterator __i = lower_bound(__k);
        // __i->first is greater than or equivalent to __k.
        if (__i == end() || key_comp()(__k, (*__i).first))
          __i = insert(__i, value_type(__k, _Tp()));
        return (*__i).second;
      }
      void swap(map<_Key,_Tp,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); }
    
      // 插入/删除操作
      // 注意以下insert操作返回的型别
      // 返回值型别是一个pair,由一个迭代器和一个bool值组成,后者表示插入成功与否,成功的话前者即指向被插入的那个元素
      pair<iterator,bool> insert(const value_type& __x) 
        { return _M_t.insert_unique(__x); }
      iterator insert(iterator position, const value_type& __x)
        { return _M_t.insert_unique(position, __x); }
    #ifdef __STL_MEMBER_TEMPLATES
      template <class _InputIterator>
      void insert(_InputIterator __first, _InputIterator __last) {
        _M_t.insert_unique(__first, __last);
      }
    #else
      void insert(const value_type* __first, const value_type* __last) {
        _M_t.insert_unique(__first, __last);
      }
      void insert(const_iterator __first, const_iterator __last) {
        _M_t.insert_unique(__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); }
      // 清除map
      void clear() { _M_t.clear(); }
    
      // map操作
      // 查找
      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.find(__x) == _M_t.end() ? 0 : 1; 
      }
      // 下边界
      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_FRIENDS 
      template <class _K1, class _T1, class _C1, class _A1>
      friend bool operator== (const map<_K1, _T1, _C1, _A1>&,
                              const map<_K1, _T1, _C1, _A1>&);
      template <class _K1, class _T1, class _C1, class _A1>
      friend bool operator< (const map<_K1, _T1, _C1, _A1>&,
                             const map<_K1, _T1, _C1, _A1>&);
    #else /* __STL_TEMPLATE_FRIENDS */
      friend bool __STD_QUALIFIER
      operator== __STL_NULL_TMPL_ARGS (const map&, const map&);
      friend bool __STD_QUALIFIER
      operator< __STL_NULL_TMPL_ARGS (const map&, const map&);
    #endif /* __STL_TEMPLATE_FRIENDS */
    };
    
    template <class _Key, class _Tp, class _Compare, class _Alloc>
    inline bool operator==(const map<_Key,_Tp,_Compare,_Alloc>& __x, 
                           const map<_Key,_Tp,_Compare,_Alloc>& __y) {
      return __x._M_t == __y._M_t;
    }
    
    template <class _Key, class _Tp, class _Compare, class _Alloc>
    inline bool operator<(const map<_Key,_Tp,_Compare,_Alloc>& __x, 
                          const map<_Key,_Tp,_Compare,_Alloc>& __y) {
      return __x._M_t < __y._M_t;
    }
    
    #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
    
    template <class _Key, class _Tp, class _Compare, class _Alloc>
    inline bool operator!=(const map<_Key,_Tp,_Compare,_Alloc>& __x, 
                           const map<_Key,_Tp,_Compare,_Alloc>& __y) {
      return !(__x == __y);
    }
    
    template <class _Key, class _Tp, class _Compare, class _Alloc>
    inline bool operator>(const map<_Key,_Tp,_Compare,_Alloc>& __x, 
                          const map<_Key,_Tp,_Compare,_Alloc>& __y) {
      return __y < __x;
    }
    
    template <class _Key, class _Tp, class _Compare, class _Alloc>
    inline bool operator<=(const map<_Key,_Tp,_Compare,_Alloc>& __x, 
                           const map<_Key,_Tp,_Compare,_Alloc>& __y) {
      return !(__y < __x);
    }
    
    template <class _Key, class _Tp, class _Compare, class _Alloc>
    inline bool operator>=(const map<_Key,_Tp,_Compare,_Alloc>& __x, 
                           const map<_Key,_Tp,_Compare,_Alloc>& __y) {
      return !(__x < __y);
    }
    
    template <class _Key, class _Tp, class _Compare, class _Alloc>
    inline void swap(map<_Key,_Tp,_Compare,_Alloc>& __x, 
                     map<_Key,_Tp,_Compare,_Alloc>& __y) {
      __x.swap(__y);
    }
    

multiset

  • 简介

    multiset的特性与用法与set完全相同,唯一的差别在于它允许键值重复,因为它的插入使用的是底层机制RB-tree的insert_equal()不是insert_unique()。

  • 源码分析

    template <class _Key, class _Compare __STL_DEPENDENT_DEFAULT_TMPL(less<_Key>),
              class _Alloc = __STL_DEFAULT_ALLOCATOR(_Key) >
    class multiset;
    
    template <class _Key, class _Compare, class _Alloc>
    inline bool operator==(const multiset<_Key,_Compare,_Alloc>& __x, 
                           const multiset<_Key,_Compare,_Alloc>& __y);
    
    template <class _Key, class _Compare, class _Alloc>
    inline bool operator<(const multiset<_Key,_Compare,_Alloc>& __x, 
                          const multiset<_Key,_Compare,_Alloc>& __y);
    
    template <class _Key, class _Compare, class _Alloc>
    class multiset {
      ...(省略,与set基本相同)
      // allocation/deallocation
      // 注意,multiset一定使用insert_equal()而不使用insert_unique(),set才使用insert_unique()
      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); }
    
    #ifdef __STL_MEMBER_TEMPLATES  
      template <class _InputIterator>
      void insert(_InputIterator __first, _InputIterator __last) {
        _M_t.insert_equal(__first, __last);
      }
    #else
      void 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 */
    ...(省略,与set基本相同)
    

multimap

multimap的特性与用法与map完全相同,唯一的差别在于它允许键值重复,因为它的插入使用的是底层机制RB-tree的insert\_equal()不是insert\_unique()。
  • 源码分析

    template <class _Key, class _Tp, class _Compare, class _Alloc>
    class multimap {
      ...(省略,其定义与map基本相同)
      // 分配释放
      // 注意,multimap一定使用insert_equal(),而不使用insert_unique()
      // map才使用insert_unique()。
      multimap() : _M_t(_Compare(), allocator_type()) { }
      explicit multimap(const _Compare& __comp,
                        const allocator_type& __a = allocator_type())
        : _M_t(__comp, __a) { }
    
    #ifdef __STL_MEMBER_TEMPLATES  
      template <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); }
    #else
      multimap(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) { }
      // 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_TEMPLATES  
      template <class _InputIterator>
      void insert(_InputIterator __first, _InputIterator __last) {
        _M_t.insert_equal(__first, __last);
      }
    #else
      void 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:
    ...
    
  • 参考文献

    STL源码剖析——侯捷

    STL源码

你可能感兴趣的:(set,map,STL,Multimap,multiset)