Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparison operator overloading for a struct, symmetrically comparing my struct with an int type?

I'm trying to overload these operators: <, <=, ==, >=, >, and maybe later !=, in a struct.

It seems that comparing an object of the struct with another object of the same struct is easy, because when overloading the operator for that scenario, the definition is automatically symmetric.

But what if I want to compare my struct FOOD to an int? This is also easy as long as FOOD comes first, however, what about the scenario when the int comes first? How do I define that without g++ giving me so many "must contain exactly one argument" errors?

I realize that

bool operator> (const int &, const FOOD &) const;

has problems due to the 'more than one argument' thing. I get that.

On all the forums I've search across the interwebs, everyone's solution seems to be using friend, but their difficulties are always in the context of classes, not structs. How is this done for s struct?

struct FOOD {
    int foodID;
    double price;
    bool operator> (const FOOD  &) const;       //FOOD >  FOOD
    bool operator>=(const FOOD  &) const;       //FOOD >= FOOD
    bool operator==(const FOOD  &) const;       //FOOD == FOOD
    bool operator<=(const FOOD  &) const;       //FOOD <= FOOD
    bool operator< (const FOOD  &) const;       //FOOD <  FOOD
    bool operator> (const int   &) const;       //FOOD >  int 
    bool operator>=(const int   &) const;       //FOOD >= int
    bool operator==(const int   &) const;       //FOOD == int
    bool operator<=(const int   &) const;       //FOOD <= int
    bool operator< (const int   &) const;       //FOOD <  int
    bool operator> (const int &, const FOOD &) const;   // int >  FOOD
    bool operator>=(const int &, const FOOD &) const;   // int >= FOOD
    bool operator==(const int &, const FOOD &) const;   // int == FOOD
    bool operator<=(const int &, const FOOD &) const;   // int <= FOOD
    bool operator< (const int &, const FOOD &) const;   // int <  FOOD
};

bool FOOD::operator> (const FOOD  &f) const {return foodID >  f.foodID;}//FOOD >  FOOD
bool FOOD::operator>=(const FOOD  &f) const {return foodID >= f.foodID;}//FOOD >= FOOD
bool FOOD::operator==(const FOOD  &f) const {return foodID == f.foodID;}//FOOD == FOOD
bool FOOD::operator<=(const FOOD  &f) const {return foodID <= f.foodID;}//FOOD <= FOOD
bool FOOD::operator< (const FOOD  &f) const {return foodID <  f.foodID;}//FOOD <  FOOD
bool FOOD::operator> (const int   &i) const {return foodID >  i;}   //FOOD >  int 
bool FOOD::operator>=(const int   &i) const {return foodID >= i;}   //FOOD >= int
bool FOOD::operator==(const int   &i) const {return foodID == i;}   //FOOD == int
bool FOOD::operator<=(const int   &i) const {return foodID <= i;}   //FOOD <= int
bool FOOD::operator< (const int   &i) const {return foodID <  i;}   //FOOD <  int
bool FOOD::operator> (const int &i, const FOOD &f) const {return i >  f.foodID;}// int >  FOOD
bool FOOD::operator>=(const int &i, const FOOD &f) const {return i >= f.foodID;}// int >= FOOD
bool FOOD::operator==(const int &i, const FOOD &f) const {return i == f.foodID;}// int == FOOD
bool FOOD::operator<=(const int &i, const FOOD &f) const {return i <= f.foodID;}// int <= FOOD
bool FOOD::operator< (const int &i, const FOOD &f) const {return i <  f.foodID;}// int <  FOOD

g++ gives me these errors:

structsTransAndFood.cc:64:45: error: ‘bool FOOD::operator>(const int&, const FOOD&) const’ must take exactly one argument
like image 857
HellHarvest Avatar asked Feb 16 '23 18:02

HellHarvest


2 Answers

Define it outside of the FOOD struct:

bool operator> (const int &i, const FOOD &f) {return i >  f.foodID;}

Don't forget to remove this wrong declaration from the FOOD struct:

bool operator> (const int &, const FOOD &) const; // <--- remove it

and the corresponding definition:

bool FOOD::operator> (const int &i, const FOOD &f) const {return i >  f.foodID;} // <--- remove it

Repeat the same for other operators.

Solution

You claim that you understand "more than one argument thing". However, it turns out that you don't. I don't get why you have troubles understanding what compiler and 2 people here tell you, but here is how the solution would look like:

struct FOOD {
    int foodID;
    double price;

    bool operator> (const FOOD  &) const;
    bool operator>=(const FOOD  &) const;
    bool operator==(const FOOD  &) const;
    bool operator<=(const FOOD  &) const;
    bool operator< (const FOOD  &) const;

    bool operator> (const int   &) const;
    bool operator>=(const int   &) const;
    bool operator==(const int   &) const;
    bool operator<=(const int   &) const;
    bool operator< (const int   &) const;
};

bool FOOD::operator> (const FOOD  &f) const {return foodID >  f.foodID;}
bool FOOD::operator>=(const FOOD  &f) const {return foodID >= f.foodID;}
bool FOOD::operator==(const FOOD  &f) const {return foodID == f.foodID;}
bool FOOD::operator<=(const FOOD  &f) const {return foodID <= f.foodID;}
bool FOOD::operator< (const FOOD  &f) const {return foodID <  f.foodID;}

bool FOOD::operator> (const int   &i) const {return foodID >  i;}
bool FOOD::operator>=(const int   &i) const {return foodID >= i;}
bool FOOD::operator==(const int   &i) const {return foodID == i;}
bool FOOD::operator<=(const int   &i) const {return foodID <= i;}
bool FOOD::operator< (const int   &i) const {return foodID <  i;}

bool operator> (const int &i, const FOOD &f) {return i >  f.foodID;}
bool operator>=(const int &i, const FOOD &f) {return i >= f.foodID;}
bool operator==(const int &i, const FOOD &f) {return i == f.foodID;}
bool operator<=(const int &i, const FOOD &f) {return i <= f.foodID;}
bool operator< (const int &i, const FOOD &f) {return i <  f.foodID;}
like image 90
Alexander Shukaev Avatar answered May 07 '23 08:05

Alexander Shukaev


This type of operator

bool operator> (const int &, const FOOD &) const; 

cannot be a member. A member function takes one extra, implicit parameter of type FOOD* (possibly cv qualified), so the example above actually takes three arguments. You need to make it a non-member.

I think the easiest approach would be to give your class an explicit int conversion operator

explicit operator int() const { return foodID; }

Also note that all the comparison operators can be expressed in terms of a single one, for instance bool operator< (this technique is used for example in std library associative containers)

like image 39
juanchopanza Avatar answered May 07 '23 09:05

juanchopanza