STL源码刨析:关联式容器之map

2024-08-21 04:28
文章标签 源码 容器 map 关联 stl 刨析

本文主要是介绍STL源码刨析:关联式容器之map,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

        1.前言

        2.了解容器map

        3.容器map的结构

        4.容器map的构造函数

        5.容器map的操作函数

        6.容器map的重载运算符函数


前言

        在上一篇博客中主要讲解了关联式容器set,其set的主要操作是调用RB-tree的操作函数来实现的,而本篇博客将重点讲解关联式容器map


了解容器map

        容器map的特性主要是:所有元素都会根据元素的键值自动被排序

        关于容器map中的元素,其所有元素都是pair,即是一对值。其中pair分为实值(value)和键值(key),在pair中第一个元素被视为键值,第二个元素被视为实值,在map中不允许两个元素拥有相同的键值(容器set只有实值)。具体的pair定义如下:

//pair源码实现
template<class T1, class T2>
struct pair{typedef T1 first_type;typedef T2 second_type;T1 first;T2 second;pair() : first(T1(), second()){}pair(const T1& a, const T2& b) : first(a), second(b) {}
}

        在容器map中可以通过提供的迭代器对实值进行修改,但不能修改其键值。而在容器set中,迭代器不能修改实值(它并没有键值)


容器map的结构

        在容器map中除去有关于STL的萃取定义以外,还在其中定义了仿函数用于比较容器map中的键值,具体源码如下:

//容器map的结构源码
template<class Key, class T,class Compare = less<Key>,    //默认采用递增排序class Alloc = alloc>
class map{
public:typedef Key key_type;   //键值类型typedef T data_type;    //实值类型   typedef T mapped_type;typedef pair<const Key, T> value_type;    //元素类型typedef Compare key_compare;    //键值比较函数//定义用于键值比较的仿函数class value_compare : public vinary_function<value_type, value_type, bool>{friend class map<Key, T, Compare, Alloc>;protected:Compare comp;value_compare(Compare c) : comp(c){}public:bool operator()(const value_type& x, const value_type& y) const{return comp(x.first, y.first);}};private://封装红黑树定义typedef rb_tree<key_type, value_type, select1st<value_type>,key_compare, Alloc> rep_type;rep_type t;
public://指针与常数指针typedef typename rep_type::pointer pointer;typedef typename rep_type::const_pointer const_pointer;//引用与常数引用typedef typename rep_type::reference redefence;typedef typename rep_type::const_rederence const rederence;//迭代器与常数迭代器typedef typename rep_type::iterator iterator;typedef typename rep_type::const_iterator const_iterator;//反向迭代器与常量反向迭代器typedef typename rep_type::reverse_iterator reverse_iterator;typedef typename rep_type::const_reverse_iterator const_reverse_iterator;typedef typename rep_type::size_type size_type;                //容器大小类型typedef typename rep_type::difference_type difference_type;    //迭代器间距离
}

容器map的构造函数

        在了解了容器map的模板结构后,以下是容器map的构造函数:

//容器map的构造函数
map() : t(Compare()){}
explicit map(const Compare& comp) : t(comp){}template <class InputIterator>
map(InputIterator first, InputIterator last) : t(Compare){t.insert_unique(first, last);
}template <class InputIterator>
map(InputIterator first, InputIterator last, const Compare& comp) : t(comp){t.insert_unique(first, last);
} map(const map<Key, T, Compare, Alloc>& x) : t(x.t){}
map<Key, T, Compare, Alloc>& operator=(const map<Key, T, Compare, Alloc>& x){t = x.t;return *this;
}

容器map的操作函数

        以下代码是关于map的操作函数,关于map的许多操作也是调用RB-tree的操作来实现的

//容器map的操作函数
key_compare key_comp() const { return t.key_com; }value_compare value_comp() const { return value_compare(t.key_comp()); }iterator begin() { return t.begin(); }const_iterator begin() const { return t.begin(); }iterator end() { reutrn t.end(); }const_iterator end() const { return t.end(); }reverse_iterator rbegin() { return t.rbegin(); }const_reverse_iterator rbegin() { return t.rbegin(); }reverse_iterator rend() { return t.rend(); }const_reverse_iterator rend() { return t.rend(); }bool empty() const { return t.empty(); }size_type size() const { return t.size(); }size_type max_size() const { return t.max_size(); }void swap(map<Key, T, compare, Alloc>& x) { t.swap(x.t); }pair<iterator, bool> insert(const value_type& x){return t.insert_unique(x);
}iterator insert(iterator position, const value_type& x){return t.insert_unique(position, x);
}template<class InputIterator>
void insert(InputIterator first, InputIterator last){t.insert_unique(first, last);
}void erase(iterator position) { t.rease(position); }size_type erase(const key_type& x) { return t.rease(x); }void erase(iterator first, iterator last) { t.erase(first, last); }void clear() { t.clear(); }iterator find(const key_type& x) { return t.find(x); }const_iterator find(const key_type& x) const { return t.find(x); }size_type count(const key_type& x) const { return t.count(x); }iterator lower_bound(const key_type& x) { return t.lower_bound(x); }const_iterator lower_bound(const key_type& x) const {return t.upper_bound(x);
}pair<iterator, iterator> equal_range(const key_type& x){return t.equal_range(x);
}pair<const_iterator, const_iterator> equal_range(const key_type& x) const {return t.equal_range(x);
}

容器map的重载运算符函数

//容器map的重载运算符函数
friend bool operator==_STL_NULL_TMPL_ARGS (const map&, const map&);friend bool operator<_STL_NULL_TMPL_ARGS (const map&, const map&);T& operator[](const key_type& k){return (*((insert(value_type(k, T()))).first)).second;
}template<class Key, class T, class Compare, class Alloc>
inline bool operator==(const map<Key, T, Compare, Alloc>& x,const map<Key, T, Compare, Alloc>& y){return x.t == y.t;
}template<class Key, class T, class Compare, class Alloc>
inline bool operator<(const map<Key, T, Compare, Alloc>& x,const map<Key, T, Compare, Alloc>& y){return x.t < y.t;
}

PS:由于关联式容器中的set和map大多数是基于RB-tree实现的,所以就没有过多分析其源码,想了解其内容可以具体阅读博客《STL源码刨析:红黑树(RB-tree)》

这篇关于STL源码刨析:关联式容器之map的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1092117

相关文章

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

Java ArrayList扩容机制 (源码解读)

结论:初始长度为10,若所需长度小于1.5倍原长度,则按照1.5倍扩容。若不够用则按照所需长度扩容。 一. 明确类内部重要变量含义         1:数组默认长度         2:这是一个共享的空数组实例,用于明确创建长度为0时的ArrayList ,比如通过 new ArrayList<>(0),ArrayList 内部的数组 elementData 会指向这个 EMPTY_EL

如何在Visual Studio中调试.NET源码

今天偶然在看别人代码时,发现在他的代码里使用了Any判断List<T>是否为空。 我一般的做法是先判断是否为null,再判断Count。 看了一下Count的源码如下: 1 [__DynamicallyInvokable]2 public int Count3 {4 [__DynamicallyInvokable]5 get

工厂ERP管理系统实现源码(JAVA)

工厂进销存管理系统是一个集采购管理、仓库管理、生产管理和销售管理于一体的综合解决方案。该系统旨在帮助企业优化流程、提高效率、降低成本,并实时掌握各环节的运营状况。 在采购管理方面,系统能够处理采购订单、供应商管理和采购入库等流程,确保采购过程的透明和高效。仓库管理方面,实现库存的精准管理,包括入库、出库、盘点等操作,确保库存数据的准确性和实时性。 生产管理模块则涵盖了生产计划制定、物料需求计划、

K8S(Kubernetes)开源的容器编排平台安装步骤详解

K8S(Kubernetes)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。以下是K8S容器编排平台的安装步骤、使用方式及特点的概述: 安装步骤: 安装Docker:K8S需要基于Docker来运行容器化应用程序。首先要在所有节点上安装Docker引擎。 安装Kubernetes Master:在集群中选择一台主机作为Master节点,安装K8S的控制平面组件,如AP

Spring框架5 - 容器的扩展功能 (ApplicationContext)

private static ApplicationContext applicationContext;static {applicationContext = new ClassPathXmlApplicationContext("bean.xml");} BeanFactory的功能扩展类ApplicationContext进行深度的分析。ApplicationConext与 BeanF

Spring 源码解读:自定义实现Bean定义的注册与解析

引言 在Spring框架中,Bean的注册与解析是整个依赖注入流程的核心步骤。通过Bean定义,Spring容器知道如何创建、配置和管理每个Bean实例。本篇文章将通过实现一个简化版的Bean定义注册与解析机制,帮助你理解Spring框架背后的设计逻辑。我们还将对比Spring中的BeanDefinition和BeanDefinitionRegistry,以全面掌握Bean注册和解析的核心原理。

容器编排平台Kubernetes简介

目录 什么是K8s 为什么需要K8s 什么是容器(Contianer) K8s能做什么? K8s的架构原理  控制平面(Control plane)         kube-apiserver         etcd         kube-scheduler         kube-controller-manager         cloud-controlle

Collection List Set Map的区别和联系

Collection List Set Map的区别和联系 这些都代表了Java中的集合,这里主要从其元素是否有序,是否可重复来进行区别记忆,以便恰当地使用,当然还存在同步方面的差异,见上一篇相关文章。 有序否 允许元素重复否 Collection 否 是 List 是 是 Set AbstractSet 否

音视频入门基础:WAV专题(10)——FFmpeg源码中计算WAV音频文件每个packet的pts、dts的实现

一、引言 从文章《音视频入门基础:WAV专题(6)——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道,通过FFprobe命令可以打印WAV音频文件每个packet(也称为数据包或多媒体包)的信息,这些信息包含该packet的pts、dts: 打印出来的“pts”实际是AVPacket结构体中的成员变量pts,是以AVStream->time_base为单位的显