opCmp()

Learn how to use opCmp() for comparisons in sorting in this lesson.

We'll cover the following

opCmp() for sorting

Sort operators determine the sort orders of objects. All of the ordering operators, <, <=, >, and >=, are covered by the opCmp() member function.

For structs, the parameter of opCmp can be defined as in. However, as with opEquals, it is more efficient to define opCmp as a template that takes auto ref const:

int opCmp()(auto ref const TimeOfDay rhs) const {
    // ...
}

To reduce confusion, opEquals and opCmp must work consistently. For every two objects that opEquals returns true, opCmp must return zero.

Let’s assume that one of these four operators is used as in the following code:

if (x op y) { // ← op is one of <, <=, >, or >=

The compiler converts that expression to the following logical expression and uses the result of the new logical expression:

if (x.opCmp(y) op 0) {

Let’s consider the <= operator:

if (x <= y) {

The compiler generates the following code behind the scenes:

if (x.opCmp(y) <= 0) {

For the user-defined opCmp() to work correctly, this member function must return a result according to the following rules:

  • A negative value is returned if the left-hand object is considered to be before the right- hand object in the order chosen (ascending/descending).

  • A positive value is returned if the left-hand object is considered to be after the right-hand object.

  • Zero is returned if the objects are considered to have the same sort order.

To support those values, the return type of opCmp() must be int, not bool.

The following is a way of ordering TimeOfDay objects by first comparing the values of the hour members, and then comparing the values of the minute members (only if the hour members are equal):

int opCmp(TimeOfDay rhs) const {
    /* Note: Subtraction is a bug here if the result can overflow. 
    (See the following warning in text.) */
    return (hour == rhs.hour ? minute - rhs.minute : hour - rhs.hour);
}

This definition returns the difference between the minute values when the hour members are the same, and it returns the difference between the hour members otherwise. The return value will be a negative value when the left-hand object comes before in chronological order, a positive value if the right-hand object is before, and zero when they represent exactly the same time of day.

Warning: Using subtraction for the implementation of opCmp is a bug if the valid values of a member can cause an overflow. For example, the two objects below would be sorted incorrectly because the object with a value of -2 is calculated to be greater than the one with the value of int.max:

Get hands-on with 1400+ tech skills courses.