views:

199

answers:

5

Is it possible in C++ for the compiler/language to automatically deduce unimplemented operators?

For example, if I have:

class X
{
public:
   bool operator ==(const X &x) const;
};

Is there a way for != to be deduced implicitly?

And I'll exploit this questions for a semi-related one: How come map's only requirement from it's keys is to implement the < operator? How does it compare for equality?

+4  A: 

Regarding the related question, it's an equivalence class. Two things 'x' and 'y' are equivalent if

!(x < y) && !(y < x)
Brian
+4  A: 

boost operators can do what you want.

As for your second question: two values A and B are equal, if A is not less than B and B is not less than A.

Ralph
+2  A: 

Completely implicit deduction of most operators is not allowed by C++'s rules, but you can mostly simulate it with inheritance in the "template method design pattern" mold; an oversimplified example...:

template <typename X> class ne
{
public:
   bool operator !=(const X &x) const
   { return ! ( (*(const X*)this) == x ); }
};

class X: public ne<X>
{
   int x;
public:
   X(int x): x(x) {}
   bool operator ==(const X &other) const
   { return x == other.x; }
};

Other answers have already pointed you to a systematic library based on clever templates &c for such purposes (boost) and to the answer for your second question (once you have <, all needed comparisons, including equality, can be easily implemented in the std library code in terms of <).

Alex Martelli
This is close to the Barton-Nackman trick. But the BN trick uses inline friend functions instead of non-static member functions.
sellibitze
It also doesn't require public inheritance and casting.
sellibitze
+4  A: 

The STL already has a set of definitions.
In the namespace stl::rel_ops the following definitions can be found.

namespace std
{
  namespace rel_ops
  {
    // Uses ==
    template <class _Tp> inline bool operator!=(const _Tp& __x, const _Tp& __y);

    // Uses <
    template <class _Tp> inline bool operator>(const _Tp& __x, const _Tp& __y);
    template <class _Tp> inline bool operator<=(const _Tp& __x, const _Tp& __y);
    template <class _Tp> inline bool operator>=(const _Tp& __x, const _Tp& __y);

  } // namespace rel_ops
}

To use it you just need to do:

#include <utility>
using namespace std::rel_ops;

Though personally I would restrict the scope of the using as much as possable.

Martin York
A: 

See Barton Nackman trick on Wikipedia. It makes use of the CRTP idiom and inline friend functions.

sellibitze