代码改变世界

STL源码剖析之关联式容器map

2011-06-28 21:34  Aga.J  阅读(1063)  评论(1编辑  收藏  举报

257 Map

Map中所有元素都是以 pair的形式出现,《key,value》, 然后所有元素都会根据key来排序,当然,key不可以有相同的,而value可以有相同的。

Template<class T1, class T2>     //classT1 for key, ClassT2 for value

Struct pair

{

Typedef T1 first_type;

Typedef T2 second_type;

T1 first;

T2 second;

Pair() : fisrt(T1()), second( T2()) {}

Pair( const T1& a , const T2& b) : first(a), second(b){}

};

和set一样的在于不可以修改map的key,因为会改变到整个map的排列,而不一样的是,map可以改变元素的value,所以这样一来map的迭代器既不是一个constance iterator(key和value都不可以修改),也不是一个mutable iteration(key和value都可以修改)

【 SGI另外提供了一种以hash table为底层机制的map,称为hash_map 】

 

Map的实现

Template<class Key, class T, class Compare= less<Key>, class Alloc=alloc>

Class map

{

Public :

Typedef Key key_type ;

Typedef T data_type ;

Tyoedef T mapped_type ;

Typedef pait<const Key, T> value_type ;

Typedef Compare key_compare;

Class value_compare: public binary_function<value_type, value_type, bool>

{

  Friend class map<Key,T,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, selectlst<value_type>, key_compare,Alloc> rep_type;

Rep_type t;

//和上一篇文章介绍的set的一样底层使用的是rb_tree,上一篇文章中key和value其实都是实际的value,set中也是用key来比较,这和map是统一的。

 clip_image002

Map(): t( Compare()){}

Explicit map( const Compare& comp): t(comp){}

 

Template<class InputIterator>

Map(InputIterator first, InputIterator last) :t(compare()){t.insert_unique(first,last) ;}

 

Template<class InputIterator>

Map( InputIterator first, InputIterator last, const Compare& comp):t(comp){t.insert_unique(first, last);}

Key_compare key_comp() const{return t.key_comp()};

Value_compare value_comp() const{return value_compare(t.key_comp()};

Iterator begin(){return t.begin();}

Const_iterator begin() const{return t.begin();}

Iterator end() {return t.end();}

Const_iterator end() const{return t.end();}

Reverse_iterator rbegin() {return t.rbegin();}

Const_reverse_iterator rbegin(){return t.rbegin();}

Bool empty() const{return t.empty();}

Size_type size() const{return t.size();}

T& operator[] (const key_type& k)

{

Return( *( (insert( value_type(k,T()) )).first) ).second;

}

//这个函数短小强悍

// 首先由于实值未知,所以根据key构建一个对象,并将这个对象插入到map中。而insert则返回一个pair。First保存的是一个迭代器,表示插入成功的元素或者插入失败的旧元素,如果这时候下标操作符是左值。那么就可以将空值卡好,如果下标操作符做右值,那么可以返回插入操作的第一个元素。

} ;

clip_image004

clip_image006

279 MultiSet

和set一致,但是它允许键值重复,所以调用insert_equal 而不是inset_unique

280 Multimap

和map一致,但是它允许键值重复,所以调用insert_equal 而不是insert_unique