C++ Logo

std-proposals

Advanced search

Re: Auto-generated comparison operators in class

From: Walt Karas <wkaras_at_[hidden]>
Date: Fri, 27 Dec 2019 18:57:31 +0000 (UTC)
Message: 1
Date: Thu, 26 Dec 2019 13:31:45 -0500
From: Edward Karak <edkharakh_at_[hidden]>
To: std-proposals_at_[hidden]
Subject: [std-proposals] Auto-generated comparison operators in class
Message-ID:
    <CAMsy88+7i2Lx2HcWsxuUCezqPYu67JQ-pNp=TfX39DkxyBn6ag_at_[hidden]>
Content-Type: text/plain; charset="utf-8"

We often want to compare class instances to each other. For example, two
date class instances. However, we have to tediously write out the
implementations for operator>, operator<, operator==, operator>=, etc.
which all have the same exact comparison logic, but simply a different
return value. This is tedious and distracts the programmer.

Instead, there should be a mechanism to write a single private comparison
member function that behaves like the comparator in qsort, returning 1, 0
or -1. Then the compiler would automatically generate all the relational
operator overloads. Here's an example:

class date {
    int yr, mo, day;
    /* new keyword: generate. Signals to the compiler that this method will
      provide the logic of the comparisons. */
    friend generate int cmp(const date &lhs, const date &rhs);
public:
    /* constructors, etc. as usual */
};

This would require the use of a new keyword, which I've called generate (maybe
a better name can be found that would minimize collision). This keyword is
used so the compiler knows that it needs to auto-generate the relational
operators for a class, and which function to call for implementing the
comparison logic itself.

The operators that the compiler will auto generate will look like this:

friend bool operator==(const date &lhs, const date &rhs)
{
    return cmp(lhs, rhs) == 0;
}

and so on and so forth for each relational operator.

If, for some reason, a programmer wants to generate all relational
operators *except* certain ones, then they can use the =delete notation. So
for the date class above, let's say we want to auto-generate all relational
operators except operator!=. Then the class would look like this:

  class date {
    int yr, mo, day;
    /* new keyword: generate. Signals to the compiler that this method will
      provide the logic of the comparisons. */
    friend generate int cmp(const date &lhs, const date &rhs);
public:
    /* constructors, etc. as usual */
    friend bool operator!=(const date &lhs, const date &rhs) = delete;
}

The only objections I can anticipate to this proposal is that this feature
would (1) significantly increase compilation times, as the compiler must
generate new code; and (2) that a new keyword would be added, which may
cause name clashes.

However, the existence of templates, which auto-generates far more code
than this would, refutes point (1). And point (2) can also be mitigated
because the Standard can alternatively require a certain name for the
comparison method, such as cmp, similar to how main is required to be the
program entry point. This would eliminate the need to invent a new keyword.
-------------- next part --------------
HTML attachment scrubbed and removed

------------------------------

I took a stab at doing something like this using the current base language:

https://github.com/ywkaras/trafficserver/blob/OrdOps/include/tscpp/util/cmp_op.h

Received on 2019-12-27 13:00:00