STL-map中的插入操作詳解

首先,我們可以如下使用map:

//#include <map>

map<string, int> simap;
map[string("hou")] = 1;
map[string("hou")] = 2;
pair<string, int> value(string("ha"), 5);
simap.insert(value);

先看insert操作的源碼:

 pair<iterator,bool> insert(const value_type& x) 
 { return t.insert_unique(x); }

其中,value_type是一個pair:

typedef pair<const Key, T> value_type;

因此上述的插入操作是向map中插入一個pair,它包含鍵和值。

[]操作在map中不包含鍵值的時候會插入鍵值,當包含鍵值時會替換相應的鍵值。這裏要說的是insert_unique(),它是map底層使用的紅黑樹中的插入操作,源碼如下:

template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
pair<typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator, bool>
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::insert_unique(const Value& v)
{
  link_type y = header;
  link_type x = root();
  bool comp = true;
  while (x != 0) {
    y = x;
    comp = key_compare(KeyOfValue()(v), key(x));
    x = comp ? left(x) : right(x);
  }
  iterator j = iterator(y);   
  if (comp)
    if (j == begin())     
      return pair<iterator,bool>(__insert(x, y, v), true);
    else
      --j;
  if (key_compare(key(j.node), KeyOfValue()(v)))//插入的值不與既有節點值重複
    return pair<iterator,bool>(__insert(x, y, v), true);
  return pair<iterator,bool>(j, false);

從上述代碼中我們可以看出,unique_insert()只會在鍵不存在的時候纔會插入成功(pair的第二個值爲true)。


接下來分析[]操作:

 T& operator[](const key_type& k) {
    return (*((insert(value_type(k, T()))).first)).second;

k是鍵,首先構造一個pair:

value_type(k, T())

然後將這個pair插入到紅黑樹中:

insert(value_type(k, T()))

插入代碼在之前已經說明過。它是唯一性的插入,即如果已經存在鍵,那麼不會插入,返回的pair中的第二個元素是false

接下來取返回pair的第一個元素,也就是個迭代器:

(insert(value_type(k, T()))).first

取迭代器指向節點的值:

*((insert(value_type(k, T()))).first))

該值實際上就是一個pair,這跟上面說的pair不一樣。此處的pair是一個鍵值對。

接下來取出它的值:

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

最後,返回該值的引用即可。

這就是map中的下標操作,這也就說明了文章剛開始時候代碼能運行的原因。

謝謝

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章