hash_multiset的特性与multiset完全相同,唯一的差别在于它的底层机制就是hashtable
也因此,hash_multiset的元素不会被自动排序
hash_multiset与hash_set唯一的区别就是在于前者从插入使用的是insert_equal
后者采用的是insert_unique
hashtable无法处理的型别,hash_multiset也没有办法处理
template <class Value,class HashFcn=hash<Value>,
class EqualKey=equal_to<Value>,
class Alloc=alloc>
class hash_multiset{
private:
typedef hashtable<Value,Value,HashFcn,identity<Value>,EqualKey,Alloc>ht;
ht rep;//底层机制是hashtable
public:
typedef typename ht::key_type key_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::const_pointer const_pointer;
typedef typename ht::const_pointer pointer;
typedef typename ht::const_reference const_reference;
typedef typename ht::const_reference reference;
typedef typename ht::const_iterator const_iterator;
typedef typename ht::const_iterator iterator;
hasher hash_funct() const{return rep.hash_funct();}
key_equal key_eq() const{return rep.key_eq();}
public:
//缺省使用大小为100的表格,将被hash table调整为最接近且较大的质数
hash_multiset():rep(100,hasher(),key_equal()){}
explicit hash_multiset(size_type n):rep(n,hf,key_equal()){}
hash_multiset(size_type n,const hasher&hf):rep(n,hf,key_equal()){}
hash_multiset(size_type n,const hasher&hf,const key_equal&eql)
:rep(n,hf,eql){}
//以下,插入操作全部使用insert_equal()允许键值重复
template<class InputIterator>
hash_multiset(InputIterator f,InputIterator l,size_type n)
:rep(n,hasher(),key_equal()){rep.insert_equal(f,l);}
template<class InputIterator>
hash_multiset(InputIterator f,InputIterator l,size_type n)
:rep(n,hasher(),key_equal()){rep.insert_equal(f,l);}
template<class InputIterator>
hash_multiset(InputIterator f,InputIterator l,size_type n,const hasher&hf)
:rep(n,hf,key_equal()){rep.insert(f,l);}
template<class InputIterator>
hash_multiset(InputIterator f,InputIterator l,size_type n,const hasher&hf,const key_equal&eal)
:rep(n,hf,eql){rep.insert_equal(f,l);}
public:
//所有的操作都有hash table的对应版本,传递调用即可
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_multiset &hs){rep.swap(hs.rep);}
friend bool operator==__STL_NULL_TMPL_ARGS(const hash_multiset&,const hash_multiset&);
iterator begin()const{return rep.begin();}
iterator end() const{return rep.end();}
public:
iterator insert(const value_type &obj){return rep.insert_equal(obj);}
template<class InputIterator>
void insert(InputIterator f,InputIterator l){rep.insert_equal(f,l);}
iterator insert_noresize(const value_type&obj){
return rep.insert_equal_noresize(obj);}
iterator find(const key_type&key)const{return rep.find(key);}
size_type count(const key_type&key)const{return rep.count(key);}
pair<iterator,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:
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 Val,class HashFcn,class EqualKey,class Alloc>
inline bool operator==(const hash_multiset<Val,HashFcn,EqualKey,Alloc>&hsl,const hash_multiset<Val,HashFcn,EqualKey,Alloc>&hs2)
{
return hs1.rep==hs2.rep;
}