
set 类型,key_type 和 value_type 是一样的,set 中保存的值就是关键字。map 中,元素时关键字-值对,即,每个元素都是一个 pair 对象,包含一个关键字和一个关联的值,由于我们不能改变一个元素的关键字,因此这些 pair 的关键字部分是 const 的。set<string>::value_type v1; //v1是string
set<string>::key_type v2; //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
注意:
只有 map 类型(unordered_map、unordered_multimap、multimap、map)才定义了 mapped_type 类型。
解引用一个关联容器将得到一个类型为容器的 value_type 的值得引用。
map<string, size_t> word_count;
auto map_it = word_count.begin();
cout << map_it->first;
cout << map_it->second;
map_it->first = "new key"; //错误,关键字是const类型
++map_it->second; //正确,可以通过迭代器改变元素的值
注意:
一个 map 的 value_type 是一个 pair 类型,可以改变 pair 的值,但是不能改变关键字成员的值。
虽然 set 同时定义了关键字 iterator 和 const_iterator 类型,但两种类型都只允许访问 set 的元素,不允许改变,即,set 的关键字是 const 类型的。
set<int> iset = { 0,1,2,3,4,5,6 };
set<int>::iterator set_it = iset.begin();
if (set_it != iset.end())
{
*set_it = 42; //错误,set中的值是只读的
}
map 和 set 都支持 begin 和 end 操作,可以使用这些函数获取迭代器,然后使用迭代器来遍历容器。
map<string, size_t> word_count;
auto map_it = word_count.cbegin();
while (map_it != word_count.cend())
{
cout << map_it->first << " occurs " << map_it->second << " times" << endl;
++map_it;
}
注意:
当使用一个迭代器遍历一个 map、multimap、set、multiset 时,迭代器按关键字升序遍历元素。
通常不会对关联容器使用泛型算法。
关键字 const 的特性意味着不能讲关联容器传递给修改元素或者重排元素的算法,而 set 的关键字是 const的,map 的键是 const 的。
关联容器可以用于只读算法,但是这类算法通常都要搜索序列,由于关联容器中的元素不能通过它们的关键字进行快速查找,因此对其使用泛型算法几乎总是个坏主意。
在实际编程时,要对关联容器使用算法的情况:
copy 将元素从一个关联容器拷贝到另一个序列。insert 将一个插入器绑定到一个关联容器,通过使用 insert,可以将关联容器当作一个目的位置来调用另一个算法。
insert 向容器中添加一个元素或一个元素范围。
map 和 set (以及对应的无序类型)包含不重复的关键字,因此插入一个已存在的元素对容器没有任何影响。
vector<int> ivec = { 2,4,6,8,2,4,6,8 };
set<int> iset;
iset.insert(ivec.cbegin(), ivec.cend()); //iset包含4个元素
iset.insert({ 1,3,5,7,1,3,5,7 }); //iset包含8个元素
对一个map insert时候,需要记住元素类型是 pair,通常需要在insert的参数类别中创建一个pair:
map<string, size_t> word_count;
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 成员是一个迭代器,只向具有给定关键字的元素。pair 的 second 成员是一个 bool 值,指出元素是插入成功还是已经存在于容器中,如果关键字已经在容器中,则 insert 什么也不做,且返回值中的 bool 部分为 false 。如果关键字不存在,元素被插入,且 bool 返回 true。map<string, size_t> word_count;
string word;
while (cin >> word)
{
auto ret = word_count.insert({ word, 1 });
if (!ret.second)
++ret.first->second; //递增计数值
}
ret 保存了 insert 的返回值,是一个 pair 类型。ret.first 是 pair 的第一个成员,是一个 map 迭代器,指向具有给定关键字的元素。ret.first-> 解引用此迭代器,提取 map 中的元素,元素也是一个 pair。ret.first->second map中元素的值部分。pair<map<string, size_t>::iterator, bool> ret = word_count.insert(make_pair<word,1>);
multi 容器中的关键字不必唯一,因此在这些类型上的调用 insert 总会插入一个元素。
multimap<string, string> authors;
//插入一个元素,关键字是:Barth,Join
authors.insert({ "Barth,Join","Sot-Weed Factor" });
//插入一个元素,关键字还是:Barth,Join
authors.insert({ "Barth,Join","Lost in the Funhouse" });
对于允许重复关键字的容器,接受单个元素的 insert 操作返回一个指向新元素的迭代器,这里不需要返回bool 值,因为总是可以插入元素。

关联容器提供了三个版本的 erase:
erase 一个迭代器来删除一个元素,返回 void 。erase 一个迭代器对来删除一个元素范围,返回 void 。erase 一个 key_type 参数,删除所有匹配关键字的元素(如果存在的话),它返回实际删除的元素的数量。
erase 总是返回0或者1。erase 可能返回大于1。
map 和unordered_map 容器提供了下标运算符和一个对应的 at 函数。set 不支持下标,因为set中没有与关键字关联的值。multimap 或一个 unordered_multimap 进行下标操作,因为这些容器中可能有多个值与关键字关联。map 下标运算符接受一个索引,即一个关键字,获取与此关键字相关联的值。如果关键字不在 map 中,会为它创建一个元素病插入到 map 中,关联值则进行值初始化。
map<string, size_t> word_count; //空的map
word_count["Anna"] = 1;
执行的操作为:
word_count 搜索关键字为 Anna 的元素,没有找到。word_count 中,关键字是一个 const string,保存 Anna,值进行值初始化,在此意味着0。关联容器提供了多种查找一个指定元素的方法:


如果只关心一个特定元素是否已在容器中,使用 find 是最佳的选择,对于关键字不允许重复的容器,使用 find 和使用 count 没什么区别,但是对于允许关键字重复的容器,count 可以统计多少个元素有相同的关键字,当然如果不需要计数,则可以直接用 find。
如果一个 multinmap 或 multiset 中有多个元素具有给定的关键字,则这些元素在容器中会相邻存储。
查找给定作者的著作:
string search_item("Alain de Botton"); //指定作者
auto entries = authors.count(search_item); //元素的数量
auto iter = authors.find(search_item); //此作者的第一本书
while(entries){
cout<<iter->second<<endl;
++iter;
--entries;
}
lower_bound 和 upper_bound 可以获取具有相同关键字的一个迭代器范围。这两个操作有可能返回的迭代器是尾后迭代器:
upper_bound 返回尾后迭代器。lower_bound 返回的也是尾后迭代器。注意:
lower_bound 返回的迭代器可能指向一个具有给定关键字的元素,但也可能不指向。如果关键字不在容器中,则lower_bound 会返回关键字的第一个安全插入点---- 不影响容器中元素顺序的插入位置。
重写上面的操作:
for (auto beg = authors.lower_bound(search_item), beg = authors.upper_bound(search_item);
beg != end; ++beg)
cout << beg->second << endl;
注意:
如果 lower_bound 和 upper_bound 返回相同的迭代器,则给定关键字不在容器中。
equal_range 函数接受一个关键字,返回一个迭代器 pair,若关键字存在,则第一个迭代器指向第一个与关键字匹配的元素,第二个迭代器指向最后一个匹配关键字之后的位置。如果没有找到匹配的元素,则两个迭代器都指向关键字可以插入的位置。
再次修改上面的程序:
for(auto pos = authors.equal_range(search_item);
pos.first != pos.second;++pos.first_
cout<< pos.first->second<<endl;原文:https://www.cnblogs.com/xiaojianliu/p/12496884.html