1

In "The C++ Standard Library" by Nicolai M. Josuttis (10th Printing December 2002), section 8.1.1 "Function Objects as Sorting Criteria" has operator() with return statement:

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

Which, based on my understanding of equivalence is correct. But the second edition of that same book (published in 2012) has changed it to:

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

which uses a blend of equivalence and equality. The errata for the 1st edition confirms the second edition is correct: http://www.josuttis.com/libbook/errata1_05.html (see Page 295, Section 8.1.1)

Why is the first incorrect? I thought for equivalence that two values were equivalent if neither precedes the other which is what the first code snippet shows. And why is the second correct even though it's employing operator== which is a test for equality, not equivalence?

ps. The second edition has this in section 10.1.1 with same section heading as first edition.

Marc Sherman
  • 2,303
  • 14
  • 22
  • 1
    They don't do the same thing; the latter fires two different operators. The result may be the same in this case, but sometimes it simply isn't feasible due to lack of equality operator overload. Assuming strict-weak ordering, the former is the best choice regardless. *Many* algorithms in the standard library rely on such ordering. Types with no equality operator overload, but offer `operator <` works in the former, pukes on the latter. Frankly I wish they would have just used [std::tie](https://en.cppreference.com/w/cpp/utility/tuple/tie) if they were bothering to update their book. – WhozCraig Jun 04 '19 at 22:21
  • There's a difference between _equivalence_ and _equality_. While they may mean the same thing in this usage (comparing strings), a "natural comparison" (that ignores case and treats digit sequences as numbers) could have two strings be equivalent but not equal. Also see this [question](https://stackoverflow.com/questions/31974941/what-is-the-difference-between-equivalence-and-equality). – 1201ProgramAlarm Jun 04 '19 at 22:23

1 Answers1

0

It seems that both do the same thing, but second version is much more readable.

Notice that

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

can be written as

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

which is the same as

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

Because we already dealt with the case p1.lastname()<p2.lastname() in first line (second line will never be evaulated if p1.lastname()<p2.lastname() is true), the second line basically boils down to

p1.lastname() == p2.lastname()
Yksisarvinen
  • 18,008
  • 2
  • 24
  • 52