一、set
- 结构特性
set/multiset以rb_tree为底层结构,其value和key是合二为一的即value就是key【元素里面只放一个东西】。
因为不能改变key值,所以使用的iterator是rb_tree的const iterator。
set中实现insert()操作时,调用的时rb_tree的insert_unique();
multiset中实现insert()操作时,调用的时rb_tree的insert_equal();
- 底层代码实现
- G2.9中
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;
private:
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有三个模板参数,但其实只需要指定一个模板参数便可,然后在内部再定义一个rb_tree类的类对象rep_type(别名) t,再通过对象t调用其内部操作来实现set的所有操作【所以从这层意义上看,set未尝不是个container adapter】。
另外这里的rb_tree因为value和key是合为一个,所以在通过value查找key时,其第三模板参数class KeyOfValue应该指定为identity<int>即传入什么就传出什么。而且由此图也可看出,set<int> iset虽然在创建时user只需指定一个模板参数int,但实际系统已经默认指定了其余的两个模板参数,而在set内部又通过定义声明等方式给class rb_tree指定了其所需的五个模板参数,并创建了rb_tree对象,从而实现相应的操作。
- VC6中
其虽不提供identity(),但在内部构造了_Kfn仿函数类,内部的操作也operator(),传进去什么就传出来什么。
二、multiset
可放置相同重复的key。