关联容器定义了下表中的类型。
对于set类型,key_type和value_type是一样的。set保存的值只有关键字,而map中,元素是pair对象,包含一个关键字和一个值。
set<string>::value_type v1;
set<string>::key_type v2;
//v1和v2都是string
map<string,int>value_type v3; //v3是一个pair<const string,int>
map<string,int>::key_type v4; //v4是一个string
map<string,int>::mapped_type v5; //v5是一个int
1、关联容器迭代器
当解引用一个关联容器迭代器时,会得到一个类型为容器value_type的引用。对map来说,first成员保存const的关键字,second成员保存值。
map<string,int> word_count;
auto map_it=word_count.begin();
//map_it是一个指向pair<const string,int>对象的引用
cout<<map_it->first<<" "; //打印关键字
cout<<map_it->second; //打印值
map_it->first="new key"; //错误,const关键字不能赋值
++map_it->second; //正确,可以通过迭代器改变元素
需要注意的是,set的迭代器是const的。set的迭代器都只允许以只读来访问set中的元素,不能修改。
set<int> iset={0,1,2,3,4,5,6,7,8,9};
set<int>::iterator set_it=iset.begin();
if(set_it!=iset.end()
{
*set_it=2987; //错误,只能读取set中的关键字
cout<<*set_it<<endl; //正确,只读
}
与其他容器类似,可以用迭代器来遍历关联容器。
map<string,int> word_count; //假设word_count中有许多元素
for(auto map_it=word_count.cbegin();map_it!=word_count.cend();++map_it)
{
cout<<map_it->first<<" "; //打印关键字
cout<<map_it->second; //打印值
}
最好不要用泛型find函数来查找关联容器中的元素,因为关联容器不能通过关键字进行快速查找。
2、添加元素
与其他容器类似,关联容器也允许向容器内插入元素。见下表。
向map做insert操作时,元素类型是pair。如果没有现成的pair对象,可以在insert的参数列表创建一个pair。
//向word_count插入word的四种方法
word_count.insert({word,1});
word_count.insert(make_pair(word,1));
word_count.insert(pair<string,size_t>(word,1));
word_count.insert(map<string,size_t>::value_type(word,1));
insert(emplace)返回值依赖于容器类型和参数。对于不包含重复关键字的容器,添加单一元素的insert(emplace)返回一个pair。pair的first成员为迭代器,指向具有给定关键字的元素,second成员是一个bool值,指出元素是插入成功还是在插入之前容器中就有该元素。如果关键字已有,则insert什么都不做,且second为false。如果关键字不存在,则插入元素,且second为true。
3、删除元素
关联容器定义了三个版本的erase,如下表所示。
4、map下标操作
map和unordered_map容器提供下标运算符和对应的at函数,如下表所示。set类型不支持下标,因为set元素本身就是关键字。map下标运算符接受关键字作为索引,以获得与关键字关联的值。
map<string,size_t> word_count;
word_count["Anna"]=1;
//插入关键字为Anna的元素,值为1
该代码会执行以下操作:
- 在word_count搜索关键字为Anna的元素,没有找到
- 将新的key-value键值对插入到word_count中,key是一个const string,value进行初始化为0
- 提取出新插入的元素,将1赋值给value
5、访问元素
关联容器提供了多种查找指定元素的方法,如下表所示。对于不允许重复关键字的容器,find和count在使用上没有什么区别。
lower_bound返回的迭代器可能指向一个具有给定关键字的元素,也可能不指向。如果关键字不在容器中,则lower_bound会返回关键字的第一个安全插入点——不影响容器中元素顺序的插入位置。
如果lower_bound和upper_bound返回相同的迭代器,则给定关键字不在容器中。