標籤:map stl c++
- Map
- map迭代器
- map初始化
- map插入元素
Map
map的特性是,所有索引值會自動被排序。所有元素都是pair類型,同時擁有實體值(value)和索引值(key)。pair的第一個元素被看做為索引值,第二個看作為實值。
同set,map不允許兩個元素有相同的索引值。又因為索引值的自動排文特性,所以在鍵類型上必須有定義的嚴格弱排序。所謂的嚴格弱排序可以理解為在索引值類型上的小於關係。
所以假如不存在兩個索引值的小於關係,則容器會視為相同的鍵。
map屬於關聯容器
map的底層是用紅/黑樹狀結構實現的
map迭代器
map的迭代器不能改變元素的索引值,但是能改變實值。因為索引值是自動排文的,改變索引值的話,會影響map的組織,所以map iterator不是一種constant iterator, 也不是一種 mutable iterator.
map的迭代器進行解引用將產生pair類型對象。
迭代器失效
map擁有和list相同的某些性質:當用戶端對它進行元素的新增(insert)和刪除的時候,在操作之前和操作之後都依然有效,當然除了被刪除的那個元素。
我們先看一下我截取的部分的map的源碼。
//map source code from map.h // modifiers: std::pair<iterator, bool> insert(const value_type& __x) { typedef typename _Base::iterator _Base_iterator; std::pair<_Base_iterator, bool> __res = _Base::insert(__x); return std::pair<iterator, bool>(iterator(__res.first, this), __res.second); } iterator insert(iterator __position, const value_type& __x) { __glibcxx_check_insert(__position); return iterator(_Base::insert(__position.base(), __x), this); } template<typename _InputIterator> void insert(_InputIterator __first, _InputIterator __last) { __glibcxx_check_valid_range(__first, __last); _Base::insert(__first, __last); } void erase(iterator __position) { __glibcxx_check_erase(__position); __position._M_invalidate(); _Base::erase(__position.base()); } size_type erase(const key_type& __x) { iterator __victim = find(__x); if (__victim == end()) return 0; else { __victim._M_invalidate(); _Base::erase(__victim.base()); return 1; } } void erase(iterator __first, iterator __last) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 151. can‘t currently clear() empty container __glibcxx_check_erase_range(__first, __last); while (__first != __last) this->erase(__first++); }
以上部分代碼不需要看起來很難,其實就是一些函式宣告和重載。
我們可以看到在使用insert的插入元素情況,除了使用開始指標和結束指標的方法來初始化,其他的都會返回新的需要的元素,利用迭代器插入的時候,會返回新元素的迭代器的位置。
所以我們在使用的時候:
iter = map.insert(iter, value);
這樣子就不會出現迭代器失效了。
但是erase就不行了,因為只有序列容器的erase返回的才是刪除後下一個元素的iterator. 而map這種關聯容器,從源碼中就可以看到傳回值是void.
所以我們在刪除操作的時候:
map.erase(iter++);
這樣子才可以。
map初始化
map<k, v> m;建立一個m的空map對象。
map<k, v> m(m2);建立一個m2的副本,k,v必須類型相同
map<k, v> m(b, e);建立迭代器b和e標記範圍內的所有元素的副本。這元素類型必須能轉換為pair<const k, v>
map插入元素
定義一個map: map <string, int> word;
1. 比較簡單,直接下標:word["alps"] = 1;
2. 使用insert: word.insert(make_pair("alps", 1));就可以了。
3. 或者typedef:typedef map<string, int>::value_type valType; word.insert(valType("alps", 1));
大致如上。
C++學習 - Map的瞭解