一、前言
关联式容器在存储元素值的同时,还会为各元素额定再装备一个值 (即是键,实质也是一个 C ++ 根底数据类型或自定义类型的元素),它的性能是在应用关联式容器的过程中,如果已知指标元素的键的值,则间接通过该键就能够找到指标元素,而无需再通过遍历整个容器的形式,提高效率。
关联式容器和序列化容器的最大区别是:关联式容器存储的元素是“键值对 <key,value>”,而且默认会依据各元素的键值的大小做升序排序 。
关联式容器所具备的这些个性,归咎于 STL 规范库在实现该类型容器时,底层选用了 红黑树 这种数据结构来组织和存储各个键值对。
二、关联式容器品种
名称 | 特点 |
---|---|
map | 定义在 <map> 头文件中,应用该容器存储的数据,其各个元素的键必须是惟一的(即不能反复),该容器会依据各元素键的大小,默认进行升序排序(调用 std::less<T>) |
set | 定义在 <set> 头文件中,应用该容器存储的数据,各个元素键和值完全相同,且各个元素的值不能反复(保障了各元素键的唯一性)。该容器会主动依据各个元素的键(其实也就是元素值)的大小进行升序排序(调用 std::less<T>) |
multimap | 定义在 <map> 头文件中,和 map 容器惟一的不同在于,multimap 容器中存储元素的键能够反复 |
multiset | 定义在 <set> 头文件中,和 set 容器惟一的不同在于,multiset 容器中存储元素的值能够反复(一旦值反复,则意味着键也是反复的) |
阐明 :此处不退出 C ++11 新增的 4 种哈希容器:unordered_map、unordered_multimap 以及 unordered_set、unordered_multiset,这 4 种也属于关联式容器,只是哈希容器底层采纳的是 哈希表 ,不是红黑树。
留神的是:关联式容器键值对写入的程序不肯定和存储的程序是一样的。
三、pair 用法
因为“键值对”不是一般类型数据,因而 stl 规范库提供了 pair 类模板,专门用来将 2 个一般元素 first 和 second 创立成一个新的元素 <first,second>。
pair 类模板定义在 <utility> 中,因而应用该类模板之前,须要引入该头文件,C++11 之前,pair 类模板提供了 3 种构造函数:
①默认构造函数,即创立空的 pair 对象
pair();
②间接应用 2 个元素初始化成 pair 对象
pair (const first_type& a, const second_type& b);
③拷贝(复制)构造函数,即借助另一个 pair 对象,创立新的 pair 对象
template<class U, class V> pair (const pair<U,V>& pr);
C++11 中,引入右值援用后,减少了 2 个构造函数:
④ 挪动构造函数
template<class U, class V> pair (pair<U,V>&& pr);
⑤ 应用右值援用参数,创立 pair 对象
template<class U, class V> pair (U&& a, V&& b);
C++11 中还有一种 pair 类模板的构造函数:
pair (piecewise_construct_t pwc, tuple<Args1...> first_args, tuple<Args2...> second_args);
然而这种办法不罕用,因而不做阐明。
四、实例
1、pair
// 默认构造函数
pair <string, int> pair1;
// 应用 2 个元素初始化 pair
pair <string, string> pair2("name", "wei");
// 调用拷贝构造函数
pair <string, string> pair3(pair2);
// 调用挪动构造函数
pair <string, string> pair4(make_pair("name", "kai"));
// 应用右值援用参数,创立 pair 对象
pair <string, string> pair5(string("name"), string("wang"));
std::cout << "pair1:" << pair1.first << " " << pair1.second << std::endl;
std::cout << "pair2:" << pair2.first << " " << pair2.second << std::endl;
std::cout << "pair3:" << pair3.first << " " << pair3.second << std::endl;
std::cout << "pair4:" << pair4.first << " " << pair4.second << std::endl;
std::cout << "pair5:" << pair5.first << " " << pair5.second << std::endl;
后果如下:
阐明:
1)make_pair() 函数是 <utility> 头文件提供的,次要是生成一个 pair 对象。因而,当咱们将 make_pair() 函数的返回值(是一个长期对象)作为参数传递给 pair() 构造函数时,其调用的是挪动构造函数,而不是拷贝构造函数。
2)C++11 容许手动为 pair 对象赋值,如:
pair1.first = "name";
pair1.second = "ying";
3)<utility> 还为 pair 对象重载了 <、<=、>、>=、==、!= 运算符,运算规定是:对于进行比拟的 2 个 pair 对象,先比拟 pair.first 元素的大小,如果相等则持续比拟 pair.second 元素的大小。
留神:对于进行比拟的 2 个 pair 对象,其对应的键和值的类型比拟雷同,否则将没有可比性,同时编译器提醒没有相匹配的运算符,即找不到适合的重载运算符。
4)pair 类模板还提供一个 swap()函数,次要是调换 2 个 pair 对象的键值对,前提是 2 个 pair 对象的 键和值的类型要雷同。