Effective STL 第19条
理解相等于等价
相等的基础是 == , 如果x==y成立,就说明x和y的值相等
对于有顺序关系的容器, 为了顺序的存在,他的比较函数是必须定义的. 在比较函数已经存在的情况下,可不可以不借助==实现两个对象是否等价的判断. 假定某个容器的默认比较函数是<, 那么obj1和obj2 是否相等的判断可以用if(!(obj1>obj2) && !(obj2<obj1))
实际上这个逻辑关系就是if(obj1==obj2)
, 只不过if(!(obj1>obj2) && !(obj2<obj1))
的表达复用了比较函数.
假定你创建一个set<string, cistringcompare> strSet,这个set 因为排序函数cistringcompare不区分大小写,所以他判断相等的时候也不区分大小写.
那么当你执行下面两行代码的时候,实际上只有第一个"ABC"被插入了. 第二个"abc"被strSet通过比较函数组成的等价判断,判定为相等,所以不会加入.
strSet.insert("ABC");
strSet.insert("ABC");
对于这种容器,如果你用容器自带的find, strSet.find("ABC") 或者 strSet.find("abc")都能找到值,因为对于这个容器,这个容器的比较函数决定了不区分大小写的特性. 但是如果你用std::find去找这个容器的元素,就只能找到"ABC"而找不到"abc", 因为std::find是基于==来进行相等判断的.
那么标准关联容器为什么不增加一个基于==的相等判断的. 原因是这样的,假定你为strSet又引入一个相等的函数,相等用==,比较用<.
那"ABC","abc" 在插入的时候,根据==,确定是不重复的,都会被加入容器,但容器在排序的时候无法区分他们. 这样的矛盾不可调和. 对于标准关联容器,希望不同的东西就一定能比较出一个顺序出来.