Would you consider this evidence of bad design?
//FooType and BarType not in the same hierarchy
bool operator==(const FooType &, const BarType &);
bool operator<(const FooType &, const BarType &);
For example, if FooType
is double
measuring seconds since epoch and BarType
is a tuple of three integers (year, month, and day) providing date in UTC, comparisons like above "make sense".
Have you seen such inter-type comparisons? Are they frowned upon in the C++ community?
The equals() method of the Object class compare the equality of two objects. The two objects will be equal if they share the same memory address. Syntax: public boolean equals(Object obj)
Comparing objects is easy, use === or Object.is(). This function returns true if they have the same reference and false if they do not.
JavaScript provides 3 ways to compare values: The strict equality operator === The loose equality operator == Object.is() function.
To start with, there's nothing wrong with using free functions instead of member functions, in fact it's recommended practice. See Scott Meyer's How Non-Member Functions Improve Encapsulation. You'll want to provide the comparisons in both directions though:
bool operator==(const FooType &, const BarType &);
bool operator==(const BarType &, const FooType &);
Second, it's perfectly acceptable to provide these comparisons if the comparisons make sense. The standard library for example allows you to compare std::complex
values for equality with floating point, but not less-than.
The one thing you want to avoid is comparisons that don't make sense. In your example one of the time values is a double, which means the comparison would occur for any floating point or integer value once you take standard promotions into account. This is probably more than you intended since there's no way to determine if any particular value represents a time. The loss of type checking means that there's a potential for unintended bugs.
Personal vision and experience
I personally do not frown upon the comparison between different types. I even encourage it, as it may improve code readability; making what you are doing seem more logical. Outside of the basic number types, and maybe a string and a character, I find it hard to give you a logical intra-type comparison, and I don't remember having met many. I have met alot of arithmetic operators used like this though.
How to use them
You should be careful with what you are doing, they are used scarcely for a reason. If you offer a function for the comparison of two different types, the outcome should be logical and what the user intuitively expected. It is also desirelable to write good documentation for it. Mark Ransom already said it, but it is good if users can compare in both directions. If you think your comparison is not sufficiently clear enough with an operator, you should think about using a named function. This is also a very good solution if your operator can have multiple meanings.
What can go wrong
You do not have full control over what the user will do with what you have written. tletnes gave a good example of this, where two integers are compared, but the outcome has no meaning. In contradiction to this, the comparison of two different types can be very right. A float and an integer both representing seconds, can be well compared.
Arithmetic operators
Next to logical, I would like to show an intra-type example with arithmetic operators. Arithmetic operators are much like logical operators when talking about intra-type usage.
Say you have an operator + for a two dimentional vector and a square. What does this do? The user might think it scales the square, but another user is sure it translates! These kinds of issues can be very frustrating to your users. You can solve this by providing good documentation, but what I personally prefer, is specifically named functions, like Translate.
Conclusion
Intra-type logical operators can be useful and make clean code, but bad usage makes everything just more complicated.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With