6

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?

asked Jul 23, 2013 at 17:53
3
  • 2
    If you have operator< and operator== defined, you could drag in the std::rel_ops namespace to provide the rest of the operators, but this is not really a good solution. Boost.Operators is the right way to do this. Commented Jul 23, 2013 at 18:02
  • Something just doesn't sit right with me using inheritance to save typing a few operators. Would rather add them manually. =) Commented Jul 23, 2013 at 18:09
  • deriving from a class that provides the functionality also has great documentation value. It is a primitive form of Concepts. Commented Jul 23, 2013 at 19:31

3 Answers 3

6

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.

answered Jul 23, 2013 at 17:56
Sign up to request clarification or add additional context in comments.

2 Comments

Dang. They generate decent default copy-constructors and such. Was hoping for a simple auto-generated operator!=(other) { return !(*this == other); }. Oh well, thanks for the answer! Will wait a bit before accepting it.
+1 the maintainer of Boost.Operators (Daniel Frey) has an uofficial port called df.operators of that library to C++11 (rvalue overloads and noexcept)
5

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.

answered Jul 23, 2013 at 18:12

4 Comments

I tend to prefer a 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.
Isn't that exactly what Boost.Operators already does for you? ;-)
@edA-qamort-ora-y Yes. That's the signature for 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.
For the version I posted, yes; for the version I actually use, no. But I was unaware of the existance of Boost operators; my actual class pre-dates Boost, and does something more. (My solution also works with just one class: you don't have to distinguish between less_than_comparable and equality_comparable. I don't know whether that is an advantage or a disadvantage.)
0

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);
 //...
};
answered Jul 23, 2013 at 19:24

6 Comments

You might need to justify that "seems... wrong." As of now I trust the boost library designers more than your unjustified opinion.
Was quoting someone else in this thread who said "Something just doesn't sit right with me using inheritance to save typing a few operators". Now, if you want to downvote me because my answer was unhelpful or didn't add anything then fine. But if you downvote me just because I am one of a large group of people who don't like 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.
-1 for recommending using #define over inheritance, with no justification for what's wrong with inheritance or why this code is exempt from the usual problems with macros.
Boost does all kinds of things that are abusive of the language, to implement features that aren't already present, as a testbed for the features later getting standardized. Boost is very well designed, but sometimes has to use hacks to get code working because of the language limitations. Whether inheriting functionality is wrong or not isn't a big issue, but saying, 'Boost does it, so it must be a good practice' isn't necessarily true. I like Boost alot! The people who design it are very intelligent and better programmers than I. But that doesn't make it good practice.
Oh, also, boost uses macroes too. Since Boost uses it, they must be good! =P deliberately tongue in cheek jab at @djechlin (just to try to lighten the mood, not actually advocating, or bashing, the use of macroes). Not intentionally bashing djechlin either. =)
|

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.