在C ++/STL中,仅使用较低的操作员完成。 Altough我不知道如何实际实施分类算法,我认为创建了其他操作是隐含的:

a > b *equals* b < a == true
a == b *equals* !(a < b) && !(b < a)

与使用Trivalue*比较函数(例如Java)相比,这对性能是否有益,或者为什么做出设计决定?

我的假设是,任何三字比较函数仍然必须本身实现这些比较,从而导致相同的性能。

**通过Trivalue比较函数,我的意思是一个比较函数,该函数的返回-1、0和1的返回-1、0和1,小于相等,高于**

更新:似乎是一艘太空船 <=> 运营商进入C ++ 20,因此显然委员会认为只有使用 operator<.

有帮助吗?

解决方案

从某种意义上说,其他两个是隐式的,但更准确的是说比较实际上不是 需要 三值比较器和C ++的类别的实现方式,该比较器不使用一个比较器来最大程度地减少比较器所需的行为。

STD :: Sort定义并专门使用类似的内容是错误的:

template <typename T, typename Cmp>
int get_tri_value(const T &a, const T &b, Cmp lessthan) {
    if (lessthan(a,b)) return -1;
    if (lessthan(b,a)) return 1;
    return 0;
}

...因为您最终会在通话的数量上以效率低下的算法 lessthan. 。如果您的算法对1返回和0返回之间的区别没有任何有用的作用,那么您就浪费了一个比较。

C ++是指“严格的弱序”。如果 < 是严格的弱点,并且 !(a < b) && !(b < a), ,不是 一定 遵循 a == b. 。它们只是在订购中“在同一地点”,并且 !(a < b) && !(b < a) 是等价关系。因此,比较器要求 sort 订单 等效类 对象,它不提供总订单。

它唯一的区别是你在说什么 !(a < b). 。对于严格的总订单,您将推论 b <= a, ,阅读“小于或等于”。对于严格的弱点,您无法定义 b <= a 意思是 b < a || b == a 这是真的。 C ++对此很奇特,并且由于它允许操作员几乎必须超载它,因为人们超载操作员需要行话,以便告诉用户他们的代码对操作员的联系,他们可以期望。 Java确实谈论了比较器,并且标题与平等一致,这就是您所需要的。 C ++必须处理<,>,==,<=,> =,分配后的条件等等。

C ++在API中采用了相当纯粹的数学方法,因此所有内容都是根据单个二进制关系定义的。 Java在某些方面更友好,并且更喜欢三向比较,在这种情况下,基本单元(比较)的定义更为复杂,但是从中引导的逻辑更为简单。这也意味着该类型算法每次比较获得更多信息,偶尔有用。例如,请参见“荷兰标志” QuickSort优化,当数据中有很多“在同一位置”重复项时,这是一个好处。

在这种情况下,三值比较器是速度增益。但是C ++使用比较器的一致定义进行排序以及 setmap, lower_bound 依此类推,这几乎无法从三值比较器中受益(也许可以节省一个比较,也许不是)。我猜他们决定不为特定或有限的潜在效率提高而复杂化他们的良好,一般界面。

其他提示

我在C ++中的猜测只是为了减少代码重复:一旦定义了类/类型上的比较OP,您不仅可以通过简单地编写a <b进行比较,而且还可以获得分类的设置这样的对象。

至于排序,我们只需要比操作员不太介绍,为什么还要介绍其他内容? :)

如果您指的是std :: sart(),则仅使用少()操作符,因为它不需要保留等效元素的相对顺序,因此它将仅需要较少()operator,而隐含地又是更大()operator。

而std :: stable_sort将保留它,但速度较慢。它需要少()操作员和双向迭代器,以交换均等()操作员来构建“ Trivalue”比较函数

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top