views:

158

answers:

3

Hi, I am trying to overload == operator to compare objects like below.

class A
{
    int a;
public:
    A(int x) { a = x; }
    bool operator==(const A& obRight)
    {
        if(a == obRight.a)
        {
            return true;
        }
        return false;
    }
};

int main()
{
    A ob(10), ob2(10), ob3(10);
    if(ob == ob2) // This equality comparison compiles fine.
        cout<<"Equal"<<endl;
     if(ob == ob2 == ob3) //This line doesn't compile as overloaded 
                          // == operator doesn't return object (returns bool)
           cout<<"Equal"<<endl;
}

As i described above, i am unable to do multiple object comparison in a single line
like if(ob == ob2 == ob3) using overloaded == operator through member function.

Should i overload using friend function ?

+11  A: 

No. You fundamentally misunderstood your operation.

if (ob == ob2 == ob3) =
if (ob == (ob2 == ob3)

Think about the types.

if (A == (A == A))
if (A == bool) // Oh dear, no == operator for bool!

You need to have

if ((ob == ob2) && (ob == ob3))
if ((A == A) && (A == A))
if (bool && bool) // fine
DeadMG
+1, just one little thing: `==` associates left-to-right.
j_random_hacker
Whoops. My mistake. Point's the same.
DeadMG
+9  A: 

As a rule you SOULD NOT DO THIS in real code.
As the usage is completely different from what other people are expecting. Unexpected things are non-intuitive, and non-intuitive makes the code hard to maintain (or understand) for somebody that is not familiar with the code base.

But as an academic exercise.

What you want is to get the operator == to return an object so that if it is used in another test it will do the test but if it is just left in a boolean context then it will auto convert to bool.

#include <iostream>
using namespace std;

template<typename T>
class Test
{
    public:
        Test(T const& v, bool s)
            :value(v)
            ,state(s)
    {}

    Test operator==(T const& rhs) const
    {
        return Test<T>(value, state && value == rhs);
    }
    operator bool() const
    {
        return state;
    }
    private:
        T const&    value;
        bool        state;
};

class A
{
    int a;
    public:
    A(int x) { a = x; }
    Test<A> operator==(const A& obRight) const
    {
        return Test<A>(*this, a == obRight.a);
    }
};

int main()
{
    A ob(10), ob2(10), ob3(14);
    if(ob == ob2) // This equality comparison compiles fine.
        cout<<"Equal"<<endl;
    if(ob == ob2 == ob3) 
        cout<<"Equal"<<endl;
}
Martin York
Hehehe good one :) But I think "This line doesn't compile" is misleading -- it compiles and works fine!
j_random_hacker
+1  A: 

You can create a function like this

#include<stdarg.h>
template<class T>
bool equals(size_t num, T val,...)
{
    va_list arguments;

    va_start(arguments,num);

    for(size_t i = 0; i<num; ++i)
        if(val != va_arg(arguments, int))
        {
            va_end ( arguments );
            return false;       
        }
    va_end ( arguments );
    return true;
}

and use it

if(equals(3,ob1,ob2,ob3))
    //do some stuff here
kilotaras
If `T` is a non-POD class type, the behavior is undefined when you pass values of that type through `...` arguments. It happens to be OK in this case, but it's not OK in general.
Rob Kennedy
+1, though according to the standard 5.2.2/7-8, only fundamental types and POD classes can be passed as arguments to `...`. (Which means e.g. no classes with virtual functions, constructors or destructors.)
j_random_hacker