我正在阅读 C ++ Primer(第5版)中的“模板和通用编程”部分,但我对其中的一些内容感到困惑。
在P655和P655上讨论“编写与类型无关的代码”时P656,作者说 “正文中的测试仅使用< comparisons”,因为“通过仅使用<运算符编写代码,我们减少了对比较函数可以使用的类型的要求那些类型必须支持<,但它们也不需要支持>。“。
是否有任何类型支持<但不是> ?如果是这样,为什么<具有优于>的优势。 ?我在谷歌搜索了一段时间,但我没有得到答案。有人可以给我一些例子或一些推荐链接吗?
答案 0 :(得分:3)
如果是,为什么
<
优于>
?
仅仅是惯例。字符'<'
首先出现在ASCII中,少于部分有序集的字符是可以构造比较的基元(即,集合被划分为等价组)。
如果我们有a
,b
和operator <
:
operator <( a, b )
operator <( b, a )
! operator <( b, a )
! operator <( a, b ) && ! operator <( b, a )
C ++有许多这样的约定,用于描述类型的行为方式。这些通常被称为 concepts ,即将推出的语言扩展,大写-C Concepts,将允许您查询和指定诸如less-than运算符是否定义部分排序之类的事情。
是否有任何类型支持
<
但不支持>
?
是的,很多。惯例是定义operator <
,然后忘记>
因为它是多余的。您可以使用std::relops
之类的内容自动定义>
<
,但总体而言,只是为了避免首先编写>
运算符更容易
依赖于排序的标准库的所有部分(例如std::sort
和std::map
)将永远不会使用>
。
答案 1 :(得分:2)
在某些语言(如Haskell)中,存在最小完整定义的概念。例如,如果您使用total order定义了一个新类(例如,对于有理数),则定义<=
运算符就足够了。其他运算符可以(在某些情况下自动)根据最小定义进行定义:
x > y
可以定义为! (x <= y)
x == y
可以定义为x <= y
&&
y <= x
x >= y
可以定义为x > y
||
x == y
x < y
可以定义为! (x >= y)
在这种情况下,最小定义只有一个运算符。通常,您只需要在最小的完整定义中定义运算符,这样做将减少可以推断的其他运算符的冗余定义&#34;。在您的情况下实现非必要的运算符(如>
)时,仅实现最小定义还可以降低引入错误或不一致的可能性。关键是实现一组最小的运算符通常是有益的。
关于为什么<
比>
更受欢迎,我认为这是一个选择和惯例问题。严格地说,人们可以选择实施任何最小定义。对于总订单类型,{<=
}和{>=
}均为最小完整集。所以those types must support
其中一组,but they need not also support
其余的一组。
答案 2 :(得分:1)
在某些情况下,类型可能会使用operator <
,除了用作排序键之外没有其他原因。订单不一定有意义,它只是支持您描述的非常模板化的API。例如,std::map
将根据operator <
对其所有元素进行排序,除非您为其指定不同的谓词。您可能不关心该订单是什么,您只希望能够进行快速(O(log n))查找。否则,该顺序对于该类可能完全没有意义。 (在这种情况下,您可能需要operator <
的自由函数二进制版本,而不是使其成为成员,或提供显式谓词。)
如果其他操作对您的班级有意义,那么一定要实施它们。它将使您的用户的生活更加简单。如果它简化了逻辑,你总是可以用operator <
来实现它们。
我能想到他们使用operator <
代替operator >
的唯一原因是它使命令更自然(假设您的语言是从左到右书写的)。如果将整数1到5存储在地图中,它们将被命令1&lt; 2&lt; 3&lt; 4&lt; 5.因此,在operator <(T left, T right)
的情况下,如果谓词返回true,则左操作数将更直接地在右操作数的“左侧”。
在你引用的文字再次传递之后,听起来我们说的是更多关于编写使用 operator <
的算法的人而不是编写课程的人实现 operator <
。如果您正在编写一个需要与其他人的代码一起工作的算法,并且您希望它们为您提供订购其元素的方法,那么您应该只需要operator <
。关键是要简化“客户”方面的工作。