C++ STL map容器具体解析
发布时间:2023-06-10 13:00:05 所属栏目:语言 来源:
导读:作为关联式容器的一种,map 容器存储的都是 pair 对象,也就是用 pair 类模板创建的键值对。其中,各个键值对的键和值可以是任意数据类型,包括 C++ 基本数据类型(int、double 等)、使用结构体或类自定义的类型。
作为关联式容器的一种,map 容器存储的都是 pair 对象,也就是用 pair 类模板创建的键值对。其中,各个键值对的键和值可以是任意数据类型,包括 C++ 基本数据类型(int、double 等)、使用结构体或类自定义的类型。 通常情况下,map 容器中存储的各个键值对都选用 string 字符串作为键的类型。 与此同时,在使用 map 容器存储多个键值对时,该容器会自动根据各键值对的键的大小,按照既定的规则进行排序。默认情况下,map 容器选用std::less<T>排序规则(其中 T 表示键的数据类型),其会根据键的大小对所有键值对做升序排序。当然,根据实际情况的需要,我们可以手动指定 map 容器的排序规则,既可以选用 STL 标准库中提供的其它排序规则(比如std::greater<T>),也可以自定义排序规则。 关于如何自定义 map 容器的排序规则,后续章节会做详细讲解。 另外需要注意的是,使用 map 容器存储的各个键值对,键的值既不能重复也不能被修改。换句话说,map 容器中存储的各个键值对不仅键的值独一无二,键的类型也会用 const 修饰,这意味着只要键值对被存储到 map 容器中,其键的值将不能再做任何修改。 前面提到,map 容器存储的都是 pair 类型的键值对元素,更确切的说,该容器存储的都是 pair<const K, T> 类型(其中 K 和 T 分别表示键和值的数据类型)的键值对元素。 map 容器定义在 <map> 头文件中,并位于 std 命名空间中。因此,如果想使用 map 容器,代码中应包含如下语句: #include <map> using namespace std; 注意,第二行代码不是必需的,如果不用,则后续程序中在使用 map 容器时,需手动注明 std 命名空间(强烈建议初学者使用)。 map 容器的模板定义如下: template < class Key, // 指定键(key)的类型 class T, // 指定值(value)的类型 class Compare = less<Key>, // 指定排序规则 class Alloc = allocator<pair<const Key,T> > // 指定分配器对象的类型 > class map; 可以看到,map 容器模板有 4 个参数,其中后 2 个参数都设有默认值。大多数场景中,我们只需要设定前 2 个参数的值,有些场景可能会用到第 3 个参数,但最后一个参数几乎不会用到。 创建C++ map容器的几种方法 map 容器的模板类中包含多种构造函数,因此创建 map 容器的方式也有多种,下面就几种常用的创建 map 容器的方法,做一一讲解。 1) 通过调用 map 容器类的默认构造函数,可以创建出一个空的 map 容器,比如: std::map<std::string, int>myMap; 如果程序中已经默认指定了 std 命令空间,这里可以省略 std::。 通过此方式创建出的 myMap 容器,初始状态下是空的,即没有存储任何键值对。鉴于空 map 容器可以根据需要随时添加新的键值对,因此创建空 map 容器是比较常用的。 2) 当然在创建 map 容器的同时,也可以进行初始化,比如: std::map<std::string, int>myMap{ {"C语言教程",10},{"STL教程",20} }; 由此,myMap 容器在初始状态下,就包含有 2 个键值对。 再次强调,map 容器中存储的键值对,其本质都是 pair 类模板创建的 pair 对象。因此,下面程序也可以创建出一模一样的 myMap 容器: std::map<std::string, int>myMap{std::make_pair("C语言教程",10),std::make_pair("STL教程",20)}; 3) 除此之外,在某些场景中,可以利用先前已创建好的 map 容器,再创建一个新的 map 容器。例如: std::map<std::string, int>newMap(myMap); 由此,通过调用 map 容器的拷贝(复制)构造函数,即可成功创建一个和 myMap 完全一样的 newMap 容器。 C++ 11 标准中,还为 map 容器增添了移动构造函数。当有临时的 map 对象作为参数,传递给要初始化的 map 容器时,此时就会调用移动构造函数。举个例子: #创建一个会返回临时 map 对象的函数 std::map<std::string,int> disMap() { std::map<std::string, int>tempMap{ {"C语言教程",10},{"STL教程",20} }; return tempMap; } //调用 map 类模板的移动构造函数创建 newMap 容器 std::map<std::string, int>newMap(disMap()); 注意,无论是调用复制构造函数还是调用拷贝构造函数,都必须保证这 2 个容器的类型完全一致。 4) map 类模板还支持取已建 map 容器中指定区域内的键值对,创建并初始化新的 map 容器。例如: std::map<std::string, int>myMap{ {"C语言教程",10},{"STL教程",20} }; std::map<std::string, int>newMap(++myMap.begin(), myMap.end()); 这里,通过调用 map 容器的双向迭代器,实现了在创建 newMap 容器的同时,将其初始化为包含一个 {"STL教程",20} 键值对的容器。 有关 map 容器迭代器,后续章节会做详细讲解。 5) 当然,在以上几种创建 map 容器的基础上,我们都可以手动修改 map 容器的排序规则。默认情况下,map 容器调用 std::less<T> 规则,根据容器内各键值对的键的大小,对所有键值对做升序排序。 因此,如下 2 行创建 map 容器的方式,其实是等价的: std::map<std::string, int>myMap{ {"C语言教程",10},{"STL教程",20} }; std::map<std::string, int, std::less<std::string> >myMap{ {"C语言教程",10},{"STL教程",20} }; 以上 2 中创建方式生成的 myMap 容器,其内部键值对排列的顺序为: <"C语言教程", 10> <"STL教程", 20> 下面程序手动修改了 myMap 容器的排序规则,令其作降序排序: std::map<std::string, int, std::greater<std::string> >myMap{ {"C语言教程",10},{"STL教程",20} }; 此时,myMap 容器内部键值对排列的顺序为: <"STL教程", 20> <"C语言教程", 10> 在某些特定场景中,我们还需要为 map 容器自定义排序规则,此部分知识后续将利用整整一节做重点讲解。 (编辑:汽车网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐