type
status
date
slug
summary
tags
category
icon
password
Property
关联容器支持高效的关键字查找和访问操作,2个主要的关联容器(associative-container)类型是
map
和 set
:map
中的元素是一些键值对(key-value):关键字起索引作用,值表示与索引相关联的数据。
set
中每个元素只包含一个关键字,支持高效的关键字查询操作:检查一个给定关键字是否在set
中。
标准库提供了8个关联容器,它们之间的不同体现在三个方面:
- 是
map
还是set
类型
- 是否允许保存重复的关键字
- 是否按顺序保存元素
允许重复保存关键字的容器名字都包含单词
multi
,无序保存元素的容器名字都以单词 unordered
开头:map
和multimap
类型定义在头文件map
中
set
和multiset
类型定义在头文件set
中
- 无序容器定义在头文件
unordered_map
和unordered_set
中
关联容器(有/无序)都支持通用的容器操作
关联容器不支持顺序容器特有的与位置相关的操作,如
push_front
或 back
。原因是——关联容器中元素是根据关键字存储的,所以这些操作对关联容器没有意义。而且,关联容器也不支持构造函数或插入操作这些接受一个元素值和一个数量值的操作。除了支持与顺序容器一样的通用操作之外,关联容器还提供另外一些操作和类型别名,并且无序关联容器还提供了对 hash 性能进行调优的操作。
关联容器的迭代器是双向迭代器的(bidirectional)。
定义关联容器
定义
map
时,必须指定关键字类型和值类型;定义set
时,只需指定关键字类型,因为set
中没有值。每个关联容器都定义了一个默认构造函数,其将创建一个指定类型的空容器。可以将关联容器初始化为另外一个相同类型容器的副本,或者以一系列值进行初始化,只要这些值可以转为容器的类型。在新标准下可以用列表初始化元素。
初始化
map
时,必须提供关键字类型和值类型,提供的每个键值对用花括号 {}
包围,{key, value}
。初始化 multimap 和 multiset
map
和 set
中的关键字必须唯一,multimap
和 multiset
没有此限制。key类型的要求
对于有序容器——
map
、multimap
、set
和 multiset
,关键字类型必须定义元素比较的方法。默认情况下,标准库使用关键字类型的 <
运算符来进行比较操作。在集合类型中,关键字类型就是元素类型;在映射类型中,关键字类型是元素的第一部分的类型。
传递给排序算法的可调用对象必须满足与关联容器中关键字一样的类型要求。
有序容器的 key 类型
类似于算法提供的比较操作,我们也可以给键提供我们的比较操作用于替换
<
操作符。这个操作必须符合严格弱序(strict weak ordering)。可以认为严格弱序与“小于”等同。定义的比较函数必须有以下性质:- 两个 key 不能互相“小于等于”对方;如果 k1 小于等于 k2,那么 k2 决不能小于等于 k1
- 如果 k1 小于等于 k2,并且 k2 小于等于 k3,那么 k1 必须小于等于 k3
- 如果两个键,两个 key 都不小于对方,那么可以认为这两个键是相等的,如果 k1 == k2,并且 k2 == k3 那么,k1 必须与 k3 相等
如果两个键是相等的,容器认为这两者是一样。当用作
map
的键时,那么将只要一个元素与这两个键匹配,而其中任何一个键都可以作为 map
中的键。在实际编程中,重要的是,如果一个类型定义了“行为正常”的
<
运算符,则它可以用作关键字类型。使用关键字类型的比较函数
用来组织容器元素的操作的类型也是该容器类型的一部分。如果需要使用自定义的比较操作,则必须在定义关联容器类型时提供此操作的类型。操作类型在尖括号中紧跟着元素类型给出。
当用
decltype
来表示一个函数指针时,必须提供 *
来表示我们确实需要的函数的指针,这是由于 decltype
推断出来的是函数的真实类型。当将 compareIsbn
指针作为构造函数实参时,可以直接使用其名字,而不必用 &compareIsbn
的形式,这是由于用于参数的函数名字会隐式转为函数指针。使用 map
map
类型通常被称为关联数组(associative array),关联数组类似于常规数组,不同之处在于其可以用非整数(integer)作为下标。map
中的值使用键进行查找而不是位置。从
map
中提取一个元素时,会得到一个pair
类型的对象。pair
是一个模板类型,保存两个名为 first
和 second
的公有数据成员。map
所使用的 pair
用 first
成员保存关键字,用 second
成员保存对应的值。使用 set
set
类型的 find
成员返回一个迭代器。如果给定关键字在 set
中,则迭代器指向该关键字,否则返回的是尾后迭代器。与别的容器一样,
set
是模板。想要定义一个set
,需要指定元素的类型,在上面的例子就是string
。与顺序容器一样,可以用列表初始化关联容器的元素。为了检查键是否存在,可以调用
set
的find
函数:find
函数返回一个迭代器,如果键在 set
中,那么将返回指向那个键的迭代器。如果元素没有找到,find
将返回尾后迭代器pair类型
pair
定义在头文件 utility
中。一个 pair
可以保存两个数据成员,分别命名为 first
和 second
。与容器一样,pair
是模板。在创建 pair
时必须提供两个类型名字用于表示数据成员的类型。对于两个类型是否相同没有要求:pair
的默认构造函数对数据成员进行值初始化。因此,anon
是一个包含两个空 string
的 pair
,line
保存一个空string
和一个空vector
。word_count
中的size_t
成员值为0,而string
成员被初始化为空可以给每个成员提供初始值:
pair
支持的操作:创建 pair对象的函数
C++11
中,如果函数需要返回 pair
,可以对返回值进行列表初始化。早期C++
版本中必须显式构造返回值。