STL

《Effective STL》

19《了解相等和等价的区别》

Posted by Liangjf on April 9, 2019

条目十九《了解相等和等价的区别》

在stl标准库中,find和insert两个操作都涉及到对数据的比较。但是他们是两种不同的比较,前者是基于相等(基于operator==,表达式if(x == y)),后者是基于等价(基于if(!x<y && !y<x))。

对于相等,注意的地方:

  • 对于同一个容器,基于不同比较操作,得到的结果可能是不一样的。
  • 对于两个容器,即使其中一个成员变量的值相等,但是如果重写一个空的operator==函数,那么即使这两个值,并不代表其他的值域也是相等的。

对于等价,注意的地方有:

  • 等价是基于一个有序的区间中对象值的相对位置。重点注意的是相对位置,而不是判断值的相等,是对于两个值之间的先后顺序,如果两个值没有一前一后,就是等价的了。
  • 一般不是直接根据operator<函数less函数来判断等价的,在stl的关联容器中,实际中,是我们人工添加一个判断表达式来判断容器的元素存放的顺序。

例子:

// 用于忽略大小写
struct CIStringCompare: public binary_function<string, string, bool> {
bool operator()(const string& lhs,const string& rhs) const
{
    return ciStringCompare(lhs, rhs);// 关于ciStringCompare,是怎么实现的参见条款35
}
set<string, CIStringCompare>

对于关联容器来说,都可以像上面的例子那样,自己实现一个判断等价的判别式,通过容器模板的第二个参数传进去自定义等价判别式。

注意:

  • 1.使用非成员函数的算法find,基于上面的set,会查找失败,因为非成员函数的find是基于相等
  • 2.使用成员函数find,基于上面的set,是会查找成功的,因为是基于等价的,忽略大小之后是等价的。