仅使用<通用编程中的比较

时间:2014-06-27 00:28:41

标签: c++ templates operators generic-programming

我正在阅读 C ++ Primer(第5版)中的“模板和通用编程”部分,但我对其中的一些内容感到困惑。

在P655和P655上讨论“编写与类型无关的代码”时P656,作者说 “正文中的测试仅使用< comparisons”,因为“通过仅使用<运算符编写代码,我们减少了对比较函数可以使用的类型的要求那些类型必须支持<,但它们也不需要支持>。“

是否有任何类型支持<但不是> ?如果是这样,为什么<具有优于>的优势。 ?我在谷歌搜索了一段时间,但我没有得到答案。有人可以给我一些例子或一些推荐链接吗?

3 个答案:

答案 0 :(得分:3)

  

如果是,为什么<优于>

仅仅是惯例。字符'<'首先出现在ASCII中,少于部分有序集的字符是可以构造比较的基元(即,集合被划分为等价组)。

如果我们有aboperator <

  • a&lt; b如果operator <( a, b )
  • a&gt; b如果operator <( b, a )
  • a≤b如果! operator <( b, a )
  • a = b if ! operator <( a, b ) && ! operator <( b, a )

C ++有许多这样的约定,用于描述类型的行为方式。这些通常被称为 concepts ,即将推出的语言扩展,大写-C Concepts,将允许您查询和指定诸如less-than运算符是否定义部分排序之类的事情。

  

是否有任何类型支持<但不支持>

是的,很多。惯例是定义operator <,然后忘记>因为它是多余的。您可以使用std::relops之类的内容自动定义> <,但总体而言,只是为了避免首先编写>运算符更容易

依赖于排序的标准库的所有部分(例如std::sortstd::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 <。关键是要简化“客户”方面的工作。