个人笔记-stl 关联容器

stl 关联容器

个人笔记-stl 关联容器_第1张图片

set,multiset

特性

  • 以rb\_tree为底层结构,因此有自动排序的特性,而且key与value合一
  • set/multiset 提供遍历操作及迭代器
  • 不能通过迭代器改变原始值,因为使用的是rb\_tree的const iteration
  • set key必须独一,其insert用的是rb\_tree的insert\_unique,multiset key可以重复,insert\_equal
  • set,multiset的所有操作,都转由tree来做未尝不是一个adapter
  /**  gcc/libstdc++-v3/include/bits/stl_set.h 中,完整的同文件大概有800行的样子,看的烦的一批,其实核心东西没多少
   *  @brief A standard container made up of unique keys, which can be
   *  retrieved in logarithmic time.
   *
   *  @ingroup associative_containers
   *
   *  @tparam _Key  Type of key objects.
   *  @tparam _Compare  Comparison function object type, defaults to less<_Key>.
   *  @tparam _Alloc  Allocator type, defaults to allocator<_Key>.
   *
   *  Meets the requirements of a container, a
   *  reversible container, and an
   *  associative container (using unique keys).
   *
   *  Sets support bidirectional iterators.
   *
   *  The private tree data is declared exactly the same way for set and
   *  multiset; the distinction is made entirely in how the tree functions are
   *  called (*_unique versus *_equal, same as the standard).
  */
  template,
       typename _Alloc = std::allocator<_Key> >
    class set
    {
    public:
      // typedefs:
      //@{
      /// Public typedefs.
      typedef _Key     key_type;
      typedef _Key     value_type;
      typedef _Compare key_compare;
      typedef _Compare value_compare;
      typedef _Alloc   allocator_type;
      //@}

    private:
      typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
    rebind<_Key>::other _Key_alloc_type;

      typedef _Rb_tree,
               key_compare, _Key_alloc_type> _Rep_type;
      _Rep_type _M_t;  // Red-black tree representing set.

      typedef __gnu_cxx::__alloc_traits<_Key_alloc_type> _Alloc_traits;

    public:
      //@{
      ///  Iterator-related typedefs.
      typedef typename _Alloc_traits::pointer         pointer;
      typedef typename _Alloc_traits::const_pointer     const_pointer;
      typedef typename _Alloc_traits::reference         reference;
      typedef typename _Alloc_traits::const_reference     const_reference;
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // DR 103. set::iterator is required to be modifiable,
      // but this allows modification of keys.
      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;
      //@}

      /**
       *  @brief Attempts to insert an element into the %set.
       *  @param  __x  Element to be inserted.
       *  @return  A pair, of which the first element is an iterator that points
       *           to the possibly inserted element, and the second is a bool
       *           that is true if the element was actually inserted.
       *
       *  This function attempts to insert an element into the %set.  A %set
       *  relies on unique keys and thus an element is only inserted if it is
       *  not already present in the %set.
       *
       *  Insertion requires logarithmic time.
       */
      std::pair
      insert(const value_type& __x)
      {
            std::pair __p =
              _M_t._M_insert_unique(__x);
            return std::pair(__p.first, __p.second);
      }

       /**
       *  @brief Tries to locate an element in a %set.
       *  @param  __x  Element to be located.
       *  @return  Iterator pointing to sought-after element, or end() if not
       *           found.
       *
       *  This function takes a key and tries to locate the element with which
       *  the key matches.  If successful the function returns an iterator
       *  pointing to the sought after element.  If unsuccessful it returns the
       *  past-the-end ( @c end() ) iterator.
       */
      iterator
      find(const key_type& __x)
      { return _M_t.find(__x); }

      const_iterator
      find(const key_type& __x) const
      { return _M_t.find(__x); }
    }
  /**
   *  @brief A standard container made up of elements, which can be retrieved
   *  in logarithmic time.
   *
   *  @ingroup associative_containers
   *
   *
   *  @tparam _Key  Type of key objects.
   *  @tparam _Compare  Comparison function object type, defaults to less<_Key>.
   *  @tparam _Alloc  Allocator type, defaults to allocator<_Key>.
   *
   *  Meets the requirements of a container, a
   *  reversible container, and an
   *  associative container (using equivalent
   *  keys).  For a @c multiset the key_type and value_type are Key.
   *
   *  Multisets support bidirectional iterators.
   *
   *  The private tree data is declared exactly the same way for set and
   *  multiset; the distinction is made entirely in how the tree functions are
   *  called (*_unique versus *_equal, same as the standard).
  */
  template ,
        typename _Alloc = std::allocator<_Key> >
    class multiset
    {
#ifdef _GLIBCXX_CONCEPT_CHECKS
      // concept requirements
      typedef typename _Alloc::value_type        _Alloc_value_type;
# if __cplusplus < 201103L
      __glibcxx_class_requires(_Key, _SGIAssignableConcept)
# endif
      __glibcxx_class_requires4(_Compare, bool, _Key, _Key,
                _BinaryFunctionConcept)
      __glibcxx_class_requires2(_Key, _Alloc_value_type, _SameTypeConcept)
#endif

#if __cplusplus >= 201103L
      static_assert(is_same::type, _Key>::value,
      "std::multiset must have a non-const, non-volatile value_type");
# if __cplusplus > 201703L || defined __STRICT_ANSI__
      static_assert(is_same::value,
      "std::multiset must have the same value_type as its allocator");
# endif
#endif

    public:
      // typedefs:
      typedef _Key     key_type;
      typedef _Key     value_type;
      typedef _Compare key_compare;
      typedef _Compare value_compare;
      typedef _Alloc   allocator_type;

    private:
      /// This turns a red-black tree into a [multi]set.
      typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
    rebind<_Key>::other _Key_alloc_type;

      typedef _Rb_tree,
               key_compare, _Key_alloc_type> _Rep_type;
      /// The actual tree structure.
      _Rep_type _M_t;

      typedef __gnu_cxx::__alloc_traits<_Key_alloc_type> _Alloc_traits;

    public:
      typedef typename _Alloc_traits::pointer         pointer;
      typedef typename _Alloc_traits::const_pointer     const_pointer;
      typedef typename _Alloc_traits::reference         reference;
      typedef typename _Alloc_traits::const_reference     const_reference;
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // DR 103. set::iterator is required to be modifiable,
      // but this allows modification of keys.
      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;


      /**
       *  @brief Inserts an element into the %multiset.
       *  @param  __x  Element to be inserted.
       *  @return An iterator that points to the inserted element.
       *
       *  This function inserts an element into the %multiset.  Contrary
       *  to a std::set the %multiset does not rely on unique keys and thus
       *  multiple copies of the same element can be inserted.
       *
       *  Insertion requires logarithmic time.
       */
      iterator
      insert(const value_type& __x)
      { return _M_t._M_insert_equal(__x); }


      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 214.  set::find() missing const overload
      //@{
      /**
       *  @brief Tries to locate an element in a %set.
       *  @param  __x  Element to be located.
       *  @return  Iterator pointing to sought-after element, or end() if not
       *           found.
       *
       *  This function takes a key and tries to locate the element with which
       *  the key matches.  If successful the function returns an iterator
       *  pointing to the sought after element.  If unsuccessful it returns the
       *  past-the-end ( @c end() ) iterator.
       */
      iterator
      find(const key_type& __x)
      { return _M_t.find(__x); }

      const_iterator
      find(const key_type& __x) const
      { return _M_t.find(__x); }
    }

map,multimap

特性

  • 以rb\_tree为底层结构,因此有自动排序的特性,排序依据是key
  • map/multimap 提供遍历操作及迭代器
  • 不能通过迭代器改变key,但是可以用来改变data(key+data=value)
  • map key必须独一,其insert用的是rb\_tree的insert\_unique,multiap key可以重复,insert\_equal
  • map和multimap的所有操作,都转由tree来做,未尝不是一个adapter
  • map有独特的operater[],可以用下标来访问map的data,而且If the key does not exist,a pair with that key is created using default values, which is then returned.
      /**
       *  @brief  Subscript ( @c [] ) access to %map data.
       *  @param  __k  The key for which data should be retrieved.
       *  @return  A reference to the data of the (key,data) %pair.
       *
       *  Allows for easy lookup with the subscript ( @c [] )
       *  operator.  Returns data associated with the key specified in
       *  subscript.  If the key does not exist, a pair with that key
       *  is created using default values, which is then returned.
       *
       *  Lookup requires logarithmic time.
       */
 /**
   *  @brief A standard container made up of (key,value) pairs, which can be
   *  retrieved based on a key, in logarithmic time.
   *
   *  @ingroup associative_containers
   *
   *  @tparam _Key  Type of key objects.
   *  @tparam  _Tp  Type of mapped objects.
   *  @tparam _Compare  Comparison function object type, defaults to less<_Key>.
   *  @tparam _Alloc  Allocator type, defaults to
   *                  allocator.
   *
   *  Meets the requirements of a container, a
   *  reversible container, and an
   *  associative container (using unique keys).
   *  For a @c map the key_type is Key, the mapped_type is T, and the
   *  value_type is std::pair.
   *
   *  Maps support bidirectional iterators.
   *
   *  The private tree data is declared exactly the same way for map and
   *  multimap; the distinction is made entirely in how the tree functions are
   *  called (*_unique versus *_equal, same as the standard).
  */
  template ,
        typename _Alloc = std::allocator > >
    class map
    {
    public:
      typedef _Key                    key_type;
      typedef _Tp                    mapped_type;
      typedef std::pair        value_type;
      typedef _Compare                    key_compare;
      typedef _Alloc                    allocator_type;

    private:
#ifdef _GLIBCXX_CONCEPT_CHECKS
      // concept requirements
      typedef typename _Alloc::value_type        _Alloc_value_type;
# if __cplusplus < 201103L
      __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
# endif
      __glibcxx_class_requires4(_Compare, bool, _Key, _Key,
                _BinaryFunctionConcept)
      __glibcxx_class_requires2(value_type, _Alloc_value_type, _SameTypeConcept)
#endif

#if __cplusplus >= 201103L
#if __cplusplus > 201703L || defined __STRICT_ANSI__
      static_assert(is_same::value,
      "std::map must have the same value_type as its allocator");
#endif
#endif

    public:
      class value_compare
      : public std::binary_function
      {
    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:
      /// This turns a red-black tree into a [multi]map.
      typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
    rebind::other _Pair_alloc_type;

      typedef _Rb_tree,
               key_compare, _Pair_alloc_type> _Rep_type;

      /// The actual tree structure.
      _Rep_type _M_t;

      typedef __gnu_cxx::__alloc_traits<_Pair_alloc_type> _Alloc_traits;

    public:
      // many of these are specified differently in ISO, but the following are
      // "functionally equivalent"
      typedef typename _Alloc_traits::pointer         pointer;
      typedef typename _Alloc_traits::const_pointer     const_pointer;
      typedef typename _Alloc_traits::reference         reference;
      typedef typename _Alloc_traits::const_reference     const_reference;
      typedef typename _Rep_type::iterator         iterator;
      typedef typename _Rep_type::const_iterator     const_iterator;
      typedef typename _Rep_type::size_type         size_type;
      typedef typename _Rep_type::difference_type     difference_type;
      typedef typename _Rep_type::reverse_iterator     reverse_iterator;
      typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator;
      ...
    }
  /**
   *  @brief A standard container made up of (key,value) pairs, which can be
   *  retrieved based on a key, in logarithmic time.
   *
   *  @ingroup associative_containers
   *
   *  @tparam _Key  Type of key objects.
   *  @tparam  _Tp  Type of mapped objects.
   *  @tparam _Compare  Comparison function object type, defaults to less<_Key>.
   *  @tparam _Alloc  Allocator type, defaults to
   *                  allocator.
   *
   *  Meets the requirements of a container, a
   *  reversible container, and an
   *  associative container (using equivalent
   *  keys).  For a @c multimap the key_type is Key, the mapped_type
   *  is T, and the value_type is std::pair.
   *
   *  Multimaps support bidirectional iterators.
   *
   *  The private tree data is declared exactly the same way for map and
   *  multimap; the distinction is made entirely in how the tree functions are
   *  called (*_unique versus *_equal, same as the standard).
  */
  template ,
        typename _Alloc = std::allocator > >
    class multimap
    {
    public:
      typedef _Key                    key_type;
      typedef _Tp                    mapped_type;
      typedef std::pair        value_type;
      typedef _Compare                    key_compare;
      typedef _Alloc                    allocator_type;

    private:
#ifdef _GLIBCXX_CONCEPT_CHECKS
      // concept requirements
      typedef typename _Alloc::value_type        _Alloc_value_type;
# if __cplusplus < 201103L
      __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
# endif
      __glibcxx_class_requires4(_Compare, bool, _Key, _Key,
                _BinaryFunctionConcept)
      __glibcxx_class_requires2(value_type, _Alloc_value_type, _SameTypeConcept)
#endif

#if __cplusplus >= 201103L
#if __cplusplus > 201703L || defined __STRICT_ANSI__
      static_assert(is_same::value,
      "std::multimap must have the same value_type as its allocator");
#endif
#endif

    public:
      class value_compare
      : public std::binary_function
      {
    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:
      /// This turns a red-black tree into a [multi]map.
      typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
    rebind::other _Pair_alloc_type;

      typedef _Rb_tree,
               key_compare, _Pair_alloc_type> _Rep_type;
      /// The actual tree structure.
      _Rep_type _M_t;

      typedef __gnu_cxx::__alloc_traits<_Pair_alloc_type> _Alloc_traits;

    public:
      // many of these are specified differently in ISO, but the following are
      // "functionally equivalent"
      typedef typename _Alloc_traits::pointer         pointer;
      typedef typename _Alloc_traits::const_pointer     const_pointer;
      typedef typename _Alloc_traits::reference         reference;
      typedef typename _Alloc_traits::const_reference     const_reference;
      typedef typename _Rep_type::iterator         iterator;
      typedef typename _Rep_type::const_iterator     const_iterator;
      typedef typename _Rep_type::size_type         size_type;
      typedef typename _Rep_type::difference_type     difference_type;
      typedef typename _Rep_type::reverse_iterator     reverse_iterator;
      typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator;
    }

你可能感兴趣的:(stl)