C++ STL 容器:基于红黑树模拟实现 map 与 set
在深入本节之前,建议先熟悉红黑树的基本概念与模拟实现。本文将在红黑树的基础上,逐步封装出符合 STL 规范的 set 和 map 容器。
一、STL 库中 map/set 的底层设计
std::set 和 std::map 的底层均通过红黑树(rb_tree)进行封装。观察 STL 源码可以发现一些有趣的设计细节:
- set 的模板参数:
set实例化rb_tree时,传入的两个类型参数都是Key。虽然set只存储 key,但这里传入了两个相同的类型,这是为了配合泛型模板设计。 - map 的模板参数:
map实例化rb_tree时,第二个参数是pair<const Key, T>。这表示红黑树节点实际存储的是键值对,而不仅仅是 value。 - 泛型设计的考量:如果为
map和set分别写两套红黑树代码,维护成本过高。STL 采用泛型模板,通过不同的模板参数实例化出不同行为的红黑树。第一个模板参数Key主要用于find、erase等接口定义查找键的类型;第二个模板参数则是节点实际存储的数据类型。
template<class Key,class Compare= less<Key>,class Alloc= alloc>
class set {
public:
typedef Key key_type;
typedef Key value_type;
private:
typedef rb_tree<key_type, value_type, identity<value_type>, key_compare, Alloc> rep_type;
rep_type t;
};
template<class Key,class T,class Compare= less<Key>,class Alloc= alloc>
class map {
public:
typedef Key key_type;
typedef pair<const Key, T> value_type;
private:
typedef rb_tree<key_type, value_type, select1st<value_type>, key_compare, Alloc> rep_type;
rep_type t;
};


