关联容器(STL)中的等式求值

Equality evaluation in associative containers (STL)

本文关键字:STL 关联      更新时间:2023-10-16

我知道STL关联容器(以及我猜正在排序的其他容器)使用排序标准来测试是否相等。

容器的排序条件默认为st::less,因此容器的相等性测试为:

if (! (lhs < rhs || rhs < lhs))

或类似的东西。关于这个我有几个问题…

首先,这似乎是一种奇怪的低效的方法来比较相等-为什么STL这样做?我本来希望STL容器只接受一个额外的默认参数来表示相等。

我的第二个问题更多的是关于上面if语句的求值。在c++中,要计算的语句(lhs> rhs)中有多少是正确的?它会在评估失败的那一边后停止尝试,从而节省一些效率吗?如果是,表达式的哪一部分首先求值?

在"Effective STL "中,Scott Meyers在Item 19:

对此进行了广泛的讨论。

理解相等和等价的区别

等式,如您所料,是基于operator==的。

等价性 "基于排序范围内对象值的相对顺序…在容器c中,如果两个对象在c的排序顺序中没有一个在另一个前面,则它们具有相等的值。"

Meyers是这样表达的:

!( w1 < w2 ) // it's not true that w1 < w2
&&           // and
!( w2 < w1 ) // it's not true that w2 < w1

Meyers接着重申:

这是有意义的:两个值是等价的(相对于某些)排序标准)如果两者都不优先(根据该标准)标准。)

至于为什么STL这样做:

通过只使用一个比较函数和使用等价性作为"相同"的仲裁者标准关联容器…避免那种混淆会产生于平等和等价的混合使用吗标准关联容器。

阅读第19条(它跨越了6页的大部分)来获得完整的味道。

STL关联容器

你的意思是:标准c++排序关联容器。

我希望STL容器只接受一个额外的默认参数来表示相等。

这会达到什么效果?在课本中的红黑树算法中,而不是

if (x < y)
    // ...
else if (y < x)
    // ...
else
    // equality

你会

if (x == y)
    // equality
else if (x < y)
    // ...
else
    // y < x

所以在最坏的情况下仍然有两个比较。

回应对这个答案的评论:只有一个小于操作符可以提供,使得容器更容易使用,因为不需要保持小于和等于之间的一致性。假设您有一个存储浮点数的程序。有一天,有人决定用一个近似的比较来替换位相等的float_equals函数,这个函数恰好被一些容器和他们的代码使用。如果那个人没有更新float_less函数,因为他们的代码没有使用该函数,那么您的容器代码就会神秘地中断。

(哦,在所示的示例代码中,一如既往地应用了短路)

关于第二个问题:适用于布尔表达式的标准C延迟求值规则。如果||的LHS为true,则不计算RHS

c++从左到右计算带有||的if()。计算左侧(lhs

首先,这似乎是一种奇怪的低效的比较相等的方式

是的,但是排序容器很少做这个测试。

使用strcmp这样的比较函数会更好。同时使用less-than和compare会更好。

在c++中,语句(lhs> rhs)中有多少是正确的?

在C和c++中,a && ba || ba, ba ? b : c从左到右求值,只求有用的右部分(c++中重载的 &&||,操作符除外)。

这允许几个有用的简短测试,如:p != NULL && *p > 2