Question

I have class A how to overload operator == to perform

A a,b,c;
if (a==b==c) {}

Could anyone help me?

Was it helpful?

Solution

Very short answer: NO!
Slightly longer answer: Don't try this.

Explanation: Every C++ programmer is used to have the comparison operator return a bool or something convertible to bool. Just because it's natural to type things like if (a==b).
So if the expression a==b returns a bool x, then a==b==c would mean comparing x with c. Which makes no sense at all. Even if you get it to compile, e.g. comparing ints that way, it would not yield the result you expect.

So, while there technically I can think of a solution to what you seem to want (compare if all three are equal), the right thing to do is how it is always done in C++: logically chain binary comparisons:

if (a==b && b==c) {}

for the ones who wonder about the "technical doable but oh so ugly" solution:
(DON'T DO THIS IN REAL WORLD USE! You should get fired if you do.)

template <class T>
struct multiCompareProxy {
  bool b;
  T const& t;

  explicit operator bool() const {return b;}
  multiCompareProxy operator==(T const& rhs) {
    return {b && t.equals(rhs), t};
  }
};

template <class T>
multiCompareProxy<T> operator==(T const& lhs, T const& rhs) {
  return {lhs.equals(rhs), lhs};
}

A class now just has to overload the euqals method for this to work: Example

OTHER TIPS

If for whatever reason you really wanted to do this, you'd need a proxy object like so:

struct A {};
struct Proxy {};

Proxy operator==(const A& a, const A& b) {
    return {};
}

bool operator==(const Proxy& p, const A& b) {
    return true;
}

bool operator==(const A& a, const Proxy& p) {
    return true;
}


#include <iostream>

int main() {
    A a, b, c;
    if(a == b == c) {
        std::cout << "Bad.\n";
    }
}

But don't do this. Use (a == b) && (a == c) like everyone else.

It can be done, and it's very occasionally useful as a kind of domain-specific language (DSL) for matching the notation expected by non-C++-programmers, but it should be studiously avoided for other uses as it'll confound (and annoy) programmers working on the code if this is used willy-nilly.

class A
{
    // ...

    bool equals(const A& rhs) const { return ... }

    struct X
    {
        X(const A& a, bool b) : a_(a), b_(b) { }
        X& operator==(const A& rhs) const { b_ &= a_.equals(rhs); return *this; }

        explicit operator bool() const { return b_; }
        // remove explicit pre C++11 / consider making it operator void*() ...

        const A& a_;
        mutable bool b_;
    };

    X A::operator==(const A& rhs) const
    {
        return X(*this, equals(rhs));
    }
};

(You might prefer standalone functions if you have implicit constructors).

The same kind of proxy-using hackery allows all manner of unexpected notations like 3 < x < 9 and x == a1 || a2 || a3... again, avoid them unless it'll make a huge difference to the maintainers of the code where they'll be used (and ideally that code will have very clear boundaries from the other C++ code in your system).

As an example of good uses of such techniques, consider the boost spirit library and it's unusual use of a lot of operators to provide something approximating BNF notation....

You cannot (minus the possibility of an ugly hack) overload operator==(...) to work as you have specified.

If you think about what it would do a == b would become either true or false (a bool), then you would have (<bool> == c) left. The proper way to do what you are looking to do would be some form of (a==b) && (b==c).

There are times when you can overload an operator to work as you describe, but it would have to return the same type that it takes. An example would be:

class A
{
  A& operator+=(A const& rhs)
  {
     // operator logic
     return *this;
  }
}

This case works because with a += b += c, you would perform (b += c) which would return an A&, which the remaining a.operator+=(...) accepts as an argument.

bool operator==(T const & a, T const & b) {
     return /*boolean expr*/
}

if you have a class you can do:

class MyClass {
public:
    bool operator==(T const & rhs) const {
       return /*boolean expr*/
    }
}

And don't use == twice in a row, you can't, do:

a == b && b == c

I would write:

bool operator==(const A& lhs, const A& rhs){ /* do actual comparison */ }

And use it twice with and operation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top