map的特性是,所有键值会自动被排序。所有元素都是pair类型,同时拥有实体值(value)和键值(key)。pair的第一个元素被看做为键值,第二个看作为实值。
同set,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<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 <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));
大致如上。
原文地址:http://blog.csdn.net/alps1992/article/details/45503559