条目十九《了解相等和等价的区别》
在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,是会查找成功的,因为是基于等价的,忽略大小之后是等价的。