11-2 关联容器概述
目录
- 11.2.1 定义关联容器
- 初始化multimap或multiset
- 11.2.2 关键字类型的要求
- 有序容器的关键字类型
- 使用关键字类型的比较函数
- 11.2.3 pair类型
- 声明和初始化
- 支持的操作
- 创建pair对象的函数
11.2.1 定义关联容器
//声明空容器
map word_count;
//列表初始化
set exclude = {"the","and","or"};
map authors = { {"John","James"},
{"Asten","Jane"},
{"Dikens","Charles"}};
初始化multimap或multiset
int main(){
//定义一个有20个元素的vector,保存0到9每个整数的两个拷贝
vector ivec;
for (vector::size_type i = 0; i != 10; ++i){
ivec.push_back (i) ;
ivec.push_back(i); //每个数重复保存一次
}
//iset包含来自ivec的不重复的元素;miset包含所有20个元素
set iset(ivec.cbegin(), ivec.cend()) ;
multiset miset(ivec.cbegin(), ivec.cend());
cout<< ivec.size () << endl; //打印出20
cout<< iset.size ( ) <
11.2.2 关键字类型的要求
对于有序容器map,multimap,set,multiset,关键字类型必须定义元素比较的方法
传递给排序算法的可调用对象(参见10.3.1节,第344页)必须满足与关联容器中关键字一样的类型要求
有序容器的关键字类型
可以向一个算法提供我们自己定义的比较操作(参见10.3节,第344页),与之类似,也可以提供自己定义的操作来代替关键字上的<运算符。
所提供的操作必须在关键字类型上定义一个严格弱序(strict weak ordering)。可以将严格弱序看作“小于等于”,虽然实际定义的操作可能是一个复杂的函数。无论我们怎样定义比较函数,它必须具备如下基本性质:
- 两个关键字不能同时“小于等于”对方;如果k1“小于等于”k2,那么k2绝不能“小于等于”k1。
- 如果 k1“小于等于”k2,且k2“小于等于”k3,那么k1必须“小于等于”k3。
- 如果存在两个关键字,任何一个都不“小于等于”另一个,那么我们称这两个关键字是“等价”的。如果k1“等价于”k2,且k2“等价于”k3,那么k1必须“等价于”k3。
在实际编程中,我们考虑的是一个类型是否定义了“行为正常”的<运算符,只要定义了,它就可以用作关键字类型
使用关键字类型的比较函数
假设一个类类型Sale_data未定义‘<’,此时我们可以自己定义一个比较函数传给map,来创建一个Sale_data的map【否则无法创建】
//依照isbn排序
bool compareIsbn(const Sale_data &lhs, const Sale_data &rhs){
return lhs.isbn()
创建Sale_data的map:
//bookstore中多条记录可以有相同的isbn
//bookstore中的元素以isbn顺序进行排序
multiset
bookstore(compareIsbn);
模板接受两个参数,一个指定元素类型,一个函数指针
声明时传入函数指针compareIsbn
注:和数组名表示一个指针类似,函数名就代表函数指针
11.2.3 pair类型
声明和初始化
定义在头文件utility中
有两个数据成员first和second,必须提供两个类型参数
pair anon; //保存两个string
pair word_count; //一个string一个size_t
可以在声明时直接初始化first和second成员:
pair i_to_i{1,2};
cout<
支持的操作

创建pair对象的函数
函数可以返回pair对象
pair process(vector &v){
if(!v.empty())
return
//构造一个pair并返回其拷贝
pair(v.back(), v.back().size());
else
//构造空pair并返回其拷贝
return pair();
}
除了直接定义外,还可以用make_pair来生成pair对象:
if(!v.empty())
return make_pair(v.back(), v.back().size());
新标准允许在返回pair时直接进行列表初始化:
if(!v.empty())
return {v.back(), v.back().size()};