一、map的介绍
map的模板参数说明:
可以明显看到相较于set来说,map是多了一个参数T的。
Key:键值对中key的类型。
T:键值对中value的类型。
Compare:比较器的类型,它是按照key的大小进行比较的,默认使用升序,默认情况下可以不传,如果想传,显式的传入函数指针或仿函数。
Alloc:空间配置器。
map和set同样底层都是基于红黑树的,只不过map比set多存放一个参数。
1、pair类型
往map中插入元素,肯定是要插入key和value的,insert的参数,value_type类型就是绑定的它们两个。
那value_type类型是什么类型呢?官网可以很清晰看到,它是一个pair类型。
pair就是键值对这玩意儿,它是一个类,成员变量是first和second,可以存放key和value。
template <class T1, class T2>
struct pair
{
typedef T1 first_type;
typedef T2 second_type;
T1 first;
T2 second;
pair(): first(T1()), second(T2())
{
}
pair(const T1& a, const T2& b): first(a), second(b)
{
}
};
2、insert插入元素
假设map定义的dict变量的数据类型是map<string, string>,我们应该如何插入数据呢?
① 调用pair的构造函数来插入:
pair<string, string> kv("insert", "插入");
dict.insert(kv);
② 调用pair的匿名对象来插入:
dict.insert(pair<string, string>("insert", "插入"));
可以看出匿名对象确实要方便一点。
③ 使用make_pair的方式来插入:
dict.insert(make_pair("insert", "插入"));
make_pair是一个函数模板,它被定义在std的命名空间中。
可以看到make_pair的返回值就是一个匿名对象。
④还有一个最简单的方式进行插入。
dict.insert({
"insert", "插入"});
很多容器都接受这种类似初始化列表的方式进行初始化,或者插入这些操作。
在上述的四种方法中,还是最推荐make_pair的方式进行插入。
3、遍历map(first、second的使用)
遍历map,同样都是支持迭代器和范围for的。
map<string, string>::iterator it = dict.begin();
嫌it前面的类型太长了,我们可以使用auto来简化写法。
auto it = dict.begin()
我们这样访问元素是不支持的,因为*it就是得到的pair类型,而pair中是没有支持重载流插入运算符(>>)重载的。
❌报错:
我们必须使用*it,也就是pair获取到它的成员变量first和second。
①使用重载的.运算符
cou