If I already have operator> and operator < defined (and operator ==), do I need to define operator>= and operator <=, or will the compiler declare them for me if I intentionally don't declare them?
Also, if I have operator == defined, will the compiler declare operator != for me?
3 Answers 3
No, the Compiler won't declare/define any of the operators you did not define manually. However, Boost.Operators might be to your liking - it does exactly what you want the compiler to do.
2 Comments
The compiler won't do anything itself for you here, but it's relatively simple to generate automatically by inheriting from an appropriate class, something like:
template< typename DerivedType >
class ComparisonOperators
{
public:
friend bool operator!=(
DerivedType const& lhs,
DerivedType const& rhs )
{
return !(lhs == rhs);
}
friend bool operator<=(
DerivedType const& lhs,
DerivedType const& rhs )
{
return !(rhs < lhs);
}
friend bool operator>(
DerivedType const& lhs,
DerivedType const& rhs )
{
return rhs < lhs;
}
friend bool operator>=(
DerivedType const& lhs,
DerivedType const& rhs )
{
return !(lhs < rhs);
}
protected:
~ComparisonOperators() {}
} ;
Define < and == in your class, and derive from this, and
you'll get all of the operators:
class MyClass : public ComparisonOperators<MyClass>
{
// ...
public:
bool operator==( MyClass const& other ) const;
bool operator<( MyClass const& other ) const;
// ...
};
Just a note: I've manually simplified the version I actual use,
which defines == and < as well, looks for the member
functions compare and isEqual, and uses compare for ==
and != when there is no isEqual. I don't think I've
introduced any errors, but you never know.
4 Comments
int compare(DerivedType const &o) which returns a negative, positive, or 0 value (traditional C approach). Usually == and < are very similar code so it's nice to merge them.compare, above. The rule is: only comparisons for equality: isEqual (and the relational operators will fail to compile if they're used); equality and relational, use compare; if equality can be done much faster, then you can provide both. And there's a bit of meta programming in the ComparisonOperators class which will call the right one.less_than_comparable and equality_comparable. I don't know whether that is an advantage or a disadvantage.)There are already some good answers here using boost and inheritance. But as someone noted - using inheritance for operator creation seems... wrong.
I know #defines are "taboo" in C++, but still that's what I use here.
I have a #define in my general utility include that goes like this:
#define CREATE_COMPARITORS(name) \
inline bool operator>(const name &o){return o<*this;} \
inline bool operator<=(const name &o){return not (o<*this);} \
inline bool operator>=(const name &o){return not (*this<o);} \
inline bool operator!=(const name &o){return not (*this==o);}
Then if I have a class, all I need to declare is operator< and operator==:
class ttt{
//...
bool operator<(const ttt &o);
bool operator==(const ttt &o);
CREATE_COMPARITORS(ttt);
//...
};
6 Comments
Boost and how it does things, while you happen to be part of another group who do like Boost, then you're abusing your power.
operator<andoperator==defined, you could drag in thestd::rel_opsnamespace to provide the rest of the operators, but this is not really a good solution. Boost.Operators is the right way to do this.