STL 中的 map 和 set 看似功能不同,本质上都是基于红黑树的定制化封装。红黑树提供了通用的平衡二叉搜索树骨架,而 map 和 set 通过提取键的规则(KeyOfT)、控制迭代器权限以及限制键值修改,分别适配了'键值对存储'和'单一元素去重排序'的需求。
map 和 set 的封装逻辑
在封装层面,map 和 set 对红黑树内部 K 和 T 的处理有所不同。map 中 K 是 Key,T 是 pair<Key, Value>,两者 Key 一致;set 中 K 和 T 都是 Key。对于 set,K 和 T 都不能被修改,因为都承载了 Key 信息;而对于 map,Key 不可变用于排序查找,Value 可变用于存储信息。
为了实现这种差异,我们需要定义 KeyOfT 结构体来提取比较用的键。map 需要提取 pair 的 first,set 则直接返回 key。同时,map 允许普通迭代器修改 value,但 const 迭代器不能修改;set 则通常只暴露 const_iterator,防止修改元素。
namespace my_stl {
template<class K, class V>
class map {
struct MapKeyOfT {
const K& operator()(const std::pair<K, V>& kv) {
return kv.first;
}
};
public:
typedef typename RBTree<K, std::pair<const K, V>, MapKeyOfT>::iterator iterator;
typedef typename RBTree<K, std::pair<const K, V>, MapKeyOfT>::const_iterator const_iterator;
iterator begin() { return _t.begin(); }
iterator end() { return _t.end(); }
const_iterator begin() const { return .(); }
{ .(); }
V& []( K& key) {
std::pair<iterator, > ret = (std::(key, ()));
ret.first->second;
}
{
.(kv);
}
:
RBTree<K, std::pair< K, V>, MapKeyOfT> ;
};
< >
{
{
{
key;
}
};
:
RBTree<K, K, SetKeyOfT>::const_iterator iterator;
RBTree<K, K, SetKeyOfT>::const_iterator const_iterator;
{ .(); }
{ .(); }
{
std::pair< RBTree<K, K, SetKeyOfT>::iterator, > ret = .(key);
std::<iterator, >(ret.first, ret.second);
}
:
RBTree<K, K, SetKeyOfT> ;
};
}


