我知道STL关联容器(以及其他正在排序的容器)使用排序标准来测试相等性。
容器的排序标准默认为st::less,因此将对容器进行相等性测试:
if (! (lhs < rhs || rhs < lhs))或者类似的东西。关于这个我有几个问题..。
首先,这似乎是一种奇怪的低效比较平等的方式-为什么STL要这样做?我原本期望STL容器只需要一个额外的默认参数来表示相等。
我的第二个问题更多地是关于上面的if语句的总体评估。在C++中,有多少语句会被评估(lhs > rhs)是正确的?它会在评估失败的那一侧后停止尝试,从而节省一些效率吗?如果是,那么首先计算表达式的哪个部分?
发布于 2011-11-22 04:09:47
在"Effective STL“一文中,Scott Meyer在项目19中对此进行了广泛的讨论
理解相等和等价之间的区别。
正如您所期望的,平等是基于operator==的。
等价性“是基于对象值在排序范围内的相对顺序……如果在c的排序顺序中,两个对象都不在另一个对象之前,那么两个对象在容器c中具有等价值。”
迈尔斯是这样表达的:
!( w1 < w2 ) // it's not true that w1 < w2
&& // and
!( w2 < w1 ) // it's not true that w2 < w1迈耶斯随后重申:
这是有道理的:如果两个值都不在另一个值之前(根据该标准),那么两个值是等价的(相对于某种排序标准)。
至于为什么STL这样做:
通过只使用一个比较函数,并使用等价作为“相同”含义的仲裁器,标准的关联容器...避免因在标准关联容器中混合使用相等和等价而引起的混淆。
自己阅读第19条(横跨6页的较大部分),以获得完整的味道。
发布于 2011-11-22 04:00:11
STL关联容器
您的意思是:标准C++排序关联容器。
我本以为
容器只需要一个额外的默认参数来表示相等。
那会有什么效果呢?在教科书中的红黑树算法中,而不是
if (x < y)
// ...
else if (y < x)
// ...
else
// equality你就会有
if (x == y)
// equality
else if (x < y)
// ...
else
// y < x因此,在最坏的情况下,仍然有两个比较。
对此答案的回应是:只需提供一个小于运算符就可以使容器更易于使用,因为不需要维护小于和等于之间的一致性。假设你有一个存储浮点数的程序。有一天,有人决定通过近似比较来替换按位相等的float_equals函数,该函数恰好被一些容器使用,但也被它们的代码使用。如果这个人不更新float_less函数,因为他们的代码不使用该函数,那么您的容器代码就会神秘地崩溃。
(哦,在所示的示例代码中,短路作用一如既往。)
发布于 2011-11-22 03:53:39
关于第二个问题:适用于布尔表达式的标准C惰性计算规则。如果||的LHS为真,则不计算RHS。
https://stackoverflow.com/questions/8217588
复制相似问题