In the Google C++ Style Guide, the section on Operator Overloading recommends against overloading any operators ("except in rare, special circumstances"). Specifically, it recommends:
In particular, do not overload
operator==
oroperator<
just so that your class can be used as a key in an STL container; instead, you should create equality and comparison functor types when declaring the container.
I'm a little fuzzy on what such a functor would look like, but my main question is, why would you want to write your own functors for this? Wouldn't defining operator<
, and using the standard std::less<T>
function, be simpler? Is there any advantage to using one over the other?
A Comparable Functor Spec.Comparable is something that a type T implements from so that an object of that type can compare itself to other objects. Comparator is something that you construct instances of so that application code can compare pairs of objects to each other.
Relational Operators Overloading in C++ which can be used to compare C++ built-in data types. You can overload any of these operators, which can be used to compare the objects of a class. Following example explains how a < operator can be overloaded and similar way you can overload other relational operators.
Which of the following operators are overloaded for functors? Explanation: () operator is overloaded to use functor property in a C++ program because this is the only operator used for a function call.
I think the message behind not defining operator< is that ordering is a property of the collection, not of the object. Different collections of the same objects may have different orderings. So you should use a separate functor used when specifying the type of the collection rather than operator<.
In practice though, a lot of your classes may have a natural ordering and that is the only ordering used in collections in your application. In other cases, the ordering may not even be relevant to the application, just the collection so it can find items later. In these cases, it makes perfect sense to define operator<.
Remember, when we're desiging object models, we're only modelling a subset of the real world. In the real world there may be umpteen different ways to rank objects of the same class, but in the application domain in which we are working there may be one that is relevant.
If code evolves to need a second ordering that is just as relevant as the first, the class should be refactored to remove operator< and to place both ranking functions in separate functors. This shows the intent that no one ranking is more important than the others.
With regard to arithmetic operators, you should not overload these unless you are implementing an arithmetic type.
Of course, there are exceptions to every rule. If you don't know whether or not you should be making an exception, you probably should not. Experience will be your guide.
I probably wouldn't go as far as the Google style guide.
I think that what they are getting at is that when you overload operator<
and operator==
, you are making a decision for every use of the type, while the functor types only apply to that collection.
If the only thing you need the comparators for is to put the item in a collection, then it's better to have a function specifically for that context rather than the operators that would apply in all contexts.
You may want to sort purchase orders chronologically, but in general, it would make sense to compare them by their total price. If we overload operator<
to compare dates so that we can load them into a collection, we are introducing the risk that another client may misuse our operator<
which they may think compares the total prices.
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