set和map都是继承 _Tree。而红黑树的修改操作需要频繁地进行比较操作,_Tree的设计将比较函数放在了模板列表中,使用trait技术,可以说最大限度的增加了自由度。
基于trait技术
_Tree容器中元素的比较操作调用trait中的comp成员对象,comp是一个仿函数对象:具体可参见_Tree::insert函数:
其中的_DEBUG_LT_PRED宏使用了comp仿函数对象去比较。
{multi}map和set都是基于_Tree,它们各自有trait的实现,set的trait叫_Tset_traits,map的trait叫_Tmap_traits,它们出了一些typename类型的定义,还有一个共同点,定义了仿函数成员对象:_Pr comp; // the comparator predicate for keys。
因为trait中有一个仿函数对象,所以set和map的构造函数中都支持传递比较仿函数对象参数。
仿函数的使用
给比较函数提供了更大的自由度,仿函数较函数指针最大好处它可以持有自己的局部状态local state。
传统比较函数只和两个被比较的元素有关,但是有时候元素间的比较需要第三个参数的参与,比如float间比较需要一个阈值。
测试代码:
通过修改my_greater的阈值,构造出不同规格的set集合。
//output:
Insert success!!!!!!!!!!!!!!!!
The item already exists!!!!!!
Insert success!!!!!!!!!!!!!!!!
1.5 0.1
Insert success!!!!!!!!!!!!!!!!
Insert success!!!!!!!!!!!!!!!!
Insert success!!!!!!!!!!!!!!!!
1.5 0.2 0.1