C++关联容器
关联容器支持普通容器操作,不支持,
- 顺序容器位置相关的操作,
push_back
等; - 构造函数或插入操作接受一个元素值和一个数量值得操作。
定义
定义一个map时必须指定关键字类型和值类型,set只需关键字类型。
初始化
可以用下面的方式来初始化,
- 同类型容器的copy;
- 指定值范围(begin和end);
- 列表初始化。
有序关联容器关键字类型的要求
有序关联容器关键字类型必须定义元素比较的方法。默认情况下,使用<
进行比较。
|
|
对于有序容器,有序容器的关键字必须是严格弱序的,可看做“小于等于”。
自定义比较操作
用于组织一个容器中元素的操作的类型也是容器类型的一部分,如果需要自定义操作,则在定义容器的时候就指明。
|
|
创建对象时,提供的操作类型(函数指针)必须与尖括号中的类型吻合。规则与函数的const形参和实参的规则一致,忽略top const。
|
|
pair
模板,接受两个类型名,pair的数据成员将有对应的类型,两个类型不要求一样。
创建对象时,pair的默认构造函数对数据成员进行值初始化(vector也可以)。
|
|
若函数返回pair,可对返回值进行列表初始化,不必显式构造返回值。
关联容器的操作
map中,每个元素就是一个pair对象,由于关键字不可变,因此pair的关键字部分是const。set的关键字也是const
。
|
|
关联容器的迭代器
对关联容器迭代器解引用,可得到容器的value_type
的引用。
对于set,虽然set定义了iterator
和const_iterator
,但是都不能改变set中的元素。
当迭代器遍历一个map,multimap,set或multiset时,按关键字升序遍历。
关联容器和算法
由于关键字是const
,因此不能用于修改或重排容器的算法(都需要向元素写入值)。只可用于读取元素的算法。
添加元素
insert
和emplace
可以对关联容器进行插入,
|
|
删除元素
关联容器有三个版本的erase,
|
|
map的下标
由于set并无关联值,下标操作对set无意义,故set不支持。multimap和multiset可能存在多个与某个key关联的值,故也不支持。
下标操作返回mapped_type
,是左值。如果关键字不在map中,下标操作会,
- 创建一个元素并插入,关联值将进行值初始化;
- 提取元素并赋值。
注意,
- 与vector和string不同,map的下标操作和解引用返回的类型(
mapped_type
和value_type
)不一样; - 如果元素不存在,
at
并不会创建,而是抛出out_of_range
; - 下标操作可能会改变map,对const的map无法使用;
- 对于const的map,只要
at
不修改元素,就可以用。1 2 3 4
const map<string, int> m{{"hello", 1}}; cout << m.at("hello") << endl; cout << m["hello"] << endl; // 错误,即使是普通访问 m.at("hello") = 1; // 错误
无序关联容器
使用hash function和==
来组织元素,用hash<key_type>
类型的对象生成每个元素的hash值,有序关联容器的操作可以用于无序容器。
标准库为内置类型(包括指针类型)和部分标准库类型(包括string和智能指针)类型定义了hash。但不能直接把自定义类型作为key来定义无序容器,可以
- 提供自己的hash模板版本;
- 定义hash function和
==
运算符。
|
|