【问题标题】:PersonSortCriterion in Josuttis book (1st edition vs 2nd edition)Josuttis 书中的 PersonSortCriterion(第 1 版与第 2 版)
【发布时间】:2019-06-04 22:11:09
【问题描述】:

在 Nicolai M. Josuttis 的“C++ 标准库”(2002 年 12 月第 10 次印刷)中,第 8.1.1 节“作为排序标准的函数对象”有 operator() 和 return 语句:

return p1.lastname()<p2.lastname() ||
       (!(p2.lastname()<p1.lastname()) &&
       p1.firstname()<p2.firstname());

根据我对等价的理解,这是正确的。但是同一本书的第二版(2012 年出版)已将其更改为:

return p1.lastname()<p2.lastname() ||
       (p1.lastname()==p2.lastname() &&
       p1.firstname()<p2.firstname());

它使用了等价和相等的混合。第 1 版的勘误表确认了第 2 版的正确性:http://www.josuttis.com/libbook/errata1_05.html(参见第 295 页,第 8.1.1 节)

为什么第一个不正确?我认为如果两个值都不在另一个之前,那么两个值是等价的,这就是第一个代码 sn-p 显示的内容。为什么第二个是正确的,即使它使用 operator== 来测试相等性,而不是等价性?

ps。第二版在第 10.1.1 节中有这一点,其章节标题与第一版相同。

【问题讨论】:

  • 他们不做同样的事情;后者解雇了两个不同的操作员。在这种情况下,结果可能是相同的,但有时由于缺少相等运算符重载,它根本不可行。假设严格-弱排序,前者是最好的选择。标准库中的许多 算法都依赖于这种排序。没有相等运算符重载但提供 operator &lt; 的类型适用于前者,后者适用于后者。坦率地说,如果他们想更新他们的书,我希望他们能使用std::tie
  • 等价平等是有区别的。虽然它们在这种用法(比较字符串)中可能意味着相同的东西,但“自然比较”(忽略大小写并将数字序列视为数字)可以使两个字符串等效但不相等。另见question

标签: c++ c++-standard-library


【解决方案1】:

似乎两者都做同样的事情,但第二个版本更具可读性。

注意

!(p2.lastname()<p1.lastname()) 

可以写成

!(p1.lastname() > p2.lastname())

相同
p1.lastname() <= p2.lastname()

因为我们已经在第一行处理了p1.lastname()&lt;p2.lastname() 的情况(如果p1.lastname()&lt;p2.lastname()true,则永远不会评估第二行),所以第二行基本上归结为

p1.lastname() == p2.lastname()

【讨论】:

  • 它比这更简单:如果排序是严格弱的,那么 if (aoperator<,则等价被认为是真的不需要任何额外的运算符来确定。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-22
  • 2019-11-05
  • 1970-01-01
  • 1970-01-01
  • 2015-11-11
  • 2020-08-28
  • 1970-01-01
相关资源
最近更新 更多