【STL和泛型编程】3. set、map分析(及typename起源)
前置知识:红黑树原理 【数据结构】7.平衡搜索树(AVL树和红黑树),红黑树的平衡性有利于 search 和 insert
- 红黑树的迭代器
- begin() 左侧
- end() 右侧
- 迭代顺序 5 6 7 8 10 11 12 13 15
- 不能使用迭代器修改 Key 的值,例如将 6 改成 50 会破坏红黑树的性质

1. RB-tree
在g++编译器中(4.9),rbtree在 <bits/stl_tree.h> 中定义
// Key: key; Value: Key+Data; KeyOfValue: 从Value中取出Key 注意这里的Value是Key和Data结合起来传入的类
// Compare: 比较Key大小的函数
template <class Key, class Value, class KeyOfValue, class Compare, class Allocated = alloc>
class _Rb_tree {
protected:
typedef __rb_tree_node<Value> rb_tree_node;
public:
typedef rb_tree_node* link_type;
protected:
size_type node_count; // 节点元素个数
link_type header; // 头节点指针,包括了Value, left, right, parent
Compare key_compare; // key的大小比较函数
};
- 使用案例,该rbtree的key就是value,获取key的方式就是直接返回该元素
- rbtree._M_insert_unique(5); 插入元素(无重复)
- rbtree._M_insert_equal(5); 插入元素(可以重复),可以使用 .count(5) 计算数量
_Rb_tree<int, int, identity<int>, less<int>, alloc> rbtree; // identity 类重载了括号,直接返回该元素本身
template <class T>
struct identity : public unary_function<T, T> {
const T& operator()(const T& x) const { return x; }
}; // less 重载了括号,比较大小后返回元素
template <class T>
struct less : public binary_function<T, T, bool> {
bool operator()(const T& x, const T& y) const
{ return x<y; }
};
2. set / multiset
- set 提供遍历操作以及迭代器 iterator,可以使用 ++ite 进行遍历,并且得到排序后的数据
- 无法使用迭代器修改元素值,修改值会导致破坏排序
- set insert 调用无重复插入方法,multiset insert 调用可重复插入的方法
template <class Key, class Compare = less<Key>, class Alloc = alloc>
class set {
public:
typedef Key key_type;
typedef Key value_type;
typedef Compare key_compare;
typedef Compare value_compare;
prevate:
typedef rb_tree<key_type, value_type, identity<value_type>, key_compare, Alloc> rep_type;
rep_type t; // 实际存储内容的红黑树
public:
typedef typename rep_type::const_iterator iterator; // 从set拿迭代器拿到的是 const_iterator,避免使用者使用迭代器修改元素
// ...
};
2.1 typename
typedef typename rep_type::const_iterator iterator; // STL源码的写法
typedef rep_type::const_iterator iterator; // 这样存在什么问题?
首先看类作用域下操作符 MyClass::name 调用实际上有 3 种可能:以MyClass为例子来说,MyClass::A静态数据成员,MyClass::B静态成员函数,MyClass::C嵌套类型。由于MyClass是一个完整的定义,所以编译器完全可以推断出任意一个变量究竟是什么类型的。但还有一种可能,如果是T::name呢?
class MyClass{
static int A; // 静态变量A
static int B(); // 静态成员函数B
typedef int C; // 嵌套类型C
}
以foo函数为例子,一眼看下去它的含义是定义了T类中iterator的指针并起名为iter;如果传入的是ContainsAType则完全没有问题。但如果传入的是ContainsAnotherType则会出现问题,因为在该类中定义了静态整形变量,如果有一个全局整形变量iter,则翻译后这里就会变成一个乘法表达式,二义性是不能被允许的,所以委员会引入了typename关键字
模板类型实例化前,并不知道它具体是哪个类型,而使用typename 可以直接告诉编译器这是一个类型,而非成员对象。
struct ContainsAType {
struct iterator { /* ... */ }
};
struct ContainsAnotherType {
static int iterator;
};
template <class T>
void foo() {
T::iterator * iter;
// ...
}
3. map / multimap
- map 提供遍历操作以及迭代器 iterator,可以使用 ++ite 遍历排序后的数据
- 无法使用迭代器修改 key,但允许修改 data(源码实现很巧妙,借用 pair<const Key, T> 实现)
- map insert 调用无重复插入方法,multimap insert 调用可重复插入方法
- insert(pair<long, string>(1, "HelloWorld"); 插入时应该插入一个pair
- map[5] = "Hi Five"; // 插入 (5, "Hi Five")
- map[5]; // 这个比较有趣,标准规定,如果没有 Key 5, 则创建 Key 5 和 string 的默认值
- 在multimap 不可以使用 multimap[]进行插入
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; // value 是 const Key 和 Data 的结合
typedef Compare key_compare;
prevate:
typedef rb_tree<key_type, value_type, select1st<value_type>, key_compare, Alloc> rep_type;
rep_type t; // 实际存储内容的红黑树
public:
typedef typename rep_type::iterator iterator; // 因为pair中是const key, 从而实现只能修改value不能修改key
// ...
};
【STL和泛型编程】3. set、map分析(及typename起源)的更多相关文章
- STL笔记(1)map
STL笔记(1)map STL之map ZZ from http://hi.baidu.com/liyanyang/blog/item/d5c87e1eb3ba06f41bd576cf.html 1. ...
- 调试技巧 —— 如何利用windbg + dump + map分析程序异常
调试技巧 —— 如何利用windbg + dump + map分析程序异常 逗比汪星人2011-09-04上传 调试技巧 —— 如何利用windbg + dump + map分析程序异常 http ...
- C/C++解题常用STL大礼包 含vector,map,set,queue(含优先队列) ,stack的常用用法
每次忘记都去查,真难啊 /* C/C++解题常用STL大礼包 含vector,map,set,queue(含优先队列) ,stack的常用用法 */ /* vector常用用法 */ //头文件 #i ...
- STL中的Set和Map——入门新手篇
STL中的Set和Map 先来看一段网络上的文字描述: 上图是一段关于STL中Set集合的描述,同样的,也近似适合Map的描述.上述文字中,描述了最为重要的特征: Set和Map,底层调用了红黑树的结 ...
- [转]SGI STL 红黑树(Red-Black Tree)源代码分析
STL提供了许多好用的数据结构与算法,使我们不必为做许许多多的重复劳动.STL里实现了一个树结构-Red-Black Tree,它也是STL里唯一实现的一个树状数据结构,并且它是map, multim ...
- [GeekBand] STL与泛型编程(2)
本篇文章在上一篇文章的基础上进一步介绍一些常用的容器以及STL的一些深入知识. 一. Stack和Queue 栈和队列是非常常用的两种数据结构,由deque适配而来.关于数据结构的知识这里就不在介绍了 ...
- [GeekBand] STL与泛型编程(1)
在C++语法的学习过程中,我们已经对模板有了基本的了解.泛型编程就是以模板为工具的.泛化的编程思想.本篇文章介绍了一些在之前的文章中没有涉及到的一些模板知识.泛型编程知识和几种容器.关于模板的一些重复 ...
- JMP软件中的晶圆图( Wafer Map)分析
关键词:芯片 良率分析 晶圆图 质量管理 JMP Minitab 半导体芯片的生产,简单来讲,是将电路通过各种复杂的物理化学方法制作到晶圆上,在生产的最后阶段会进行不同电性功能的测试以确保产品的功能性 ...
- C++ STL中哈希表Map 与 hash_map 介绍
0 为什么需要hash_map 用过map吧?map提供一个很常用的功能,那就是提供key-value的存储和查找功能.例如,我要记录一个人名和相应的存储,而且随时增加,要快速查找和修改: 岳不群-华 ...
- STL源码剖析(set/map)
SGI STL中set/map底层都是通过RB-tree实现的. 首先看看RB-tree结点的定义 typedef bool __rb_tree_color_type; const __rb_tree ...
随机推荐
- Solon Ai Flow 编排开发框架发布预告(效果预览)
Solon Ai 在推出 Solon Ai Mcp 后,又将推出 Solon Ai Flow. 1.Solon Ai Flow 是个啥? Solon Ai Flow 是一个智能体编排开发框架(基于 s ...
- .NET 原生驾驭 AI 新基建实战系列(八):总结篇 ── 数据库技术的革命:从结构化到非结构化再到智能化的演进
引言 随着信息技术的飞速发展,数据库技术作为数据管理与存储的核心支柱,经历了从结构化到非结构化,再到如今智能化的深刻变革.每一次技术革新都不仅是对数据处理能力的提升,更是对人类利用数据方式的重新定义. ...
- 立创杯(javabasic)
Throws关键字用于对外声明方法可能发生的异常,这样调用者在调用方法时,可以明确知道方法有异常,并进行相关处理 接口中可以包含非静态成员变量 Math.round(-1.5)//-1 round(d ...
- TPLINK路由器重启脚本(软件版本3.0.0)
家中的两个路由器全都是TPLink路由器,由于总出现时间一长就网卡的原因,写了这个重启脚本在每天凌晨五点的时候对路由器进行自动重启 使用方法: self.logindata的值为登录时的jso ...
- 前端预览和打印PDF的两种方式
最近工作中遇到了一个需求,就是前端选择表格中的某一条数据去请求后端接口,后端返回的是一个PDF文件的下载地址,但是需求不希望用户下载下来再去打印,而是直接预览展示,然后就能打印. 一开始按照网上的方式 ...
- Comparator.reverseOrder() 和 reversed()的区别
摘要:Comparator.reverseOrder() 和 reversed()的区别是前者以某字段进行倒序排列,而reversed是针对已排序数据进行处理,常常用于比较器的末尾. 在使用Str ...
- 「Note」数论方向 - 组合数学
1. 容斥原理 1.1 介绍 解决集合内计数问题. \(S\) 为集合编号集合. \[\left | \bigcup_{i\in S}A_i \right | =\sum_{T\subseteq S\ ...
- Django的Model类
1.model 用来和数据交互的(读取和传入数据) 2.orm Object Relational Mapping对象关系映射,python中的model对象和数据库中的表做映射 3.重要概念 3.1 ...
- CAN304 W1
CAN304 W1 Definition The protection afforded to an automated information system in order to attain t ...
- 开箱即用,袋鼠云上线DeepSeek AI大模型一体机!
"服务器繁忙,请稍后再试."DeepSeek于2025年初爆火后,需求量剧增,算力资源被持续压榨,处于满负荷运行状态.加之因担忧数据安全与合规,大型组织纷纷将目光投向DeepSee ...