一个结构体的比较运算符重载,如何对称地将我的结构体与 int 类型进行比较?

4
我正在尝试重载以下运算符: <<===>=>,以及可能稍后的 !=,在一个结构体中。
似乎与同一结构体的另一个对象进行比较很容易,因为当为该场景重载运算符时,定义会自动对称。
但是如果我想将我的结构体 FOOD 与一个 int 进行比较呢?只要 FOOD 在前面,这也很容易,但是如果 int 在前面怎么办?如何定义才能避免 g++ 给出太多“必须包含一个参数”的错误?
我意识到:
bool operator> (const int &, const FOOD &) const;

因为“超过一个参数”的问题而出现了一些问题。我明白这一点。
在我搜索过的所有论坛中,每个人的解决方案似乎都是使用friend,但他们的困难总是在类的上下文中,而不是结构体。如何为结构体完成此操作?
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++ 给我报了以下这些错误:

structsTransAndFood.cc:64:45: error: ‘bool FOOD::operator>(const int&, const FOOD&) const’ must take exactly one argument

结构体和类之间除了成员的默认保护级别外没有任何区别。如果需要,您可以使用operator<定义所有运算符。 - Mark Ransom
由于结构体的所有成员都是公共的,因此不需要使用“friend”来进行任何操作。 - Mark Ransom
1
由于一个int foodID似乎能够唯一地标识一个FOOD,因此您可以通过提供一个转换operator int() const;来消除所有这些比较。 - Drew Dormann
2个回答

6

将其定义在FOOD结构体之外:

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

不要忘记从FOOD结构中删除这个错误的声明:

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

以及相应的定义:

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

对于其他运算符也需要重复相同的操作。

解决方案

你声称你理解了“多个参数”的概念。然而,事实证明你并没有理解。我不明白为什么你难以理解编译器和这里的两个人告诉你的内容,但是以下是解决方案的步骤:

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;}

1
错误:‘bool FOOD::operator>(const int&, const FOOD&) const’必须只有一个参数。你理解这个错误信息了吗?在类/结构体中声明的运算符必须只有一个显式参数。在你的情况下,它有两个参数,因此你会得到这个错误。要解决这个问题,只需按照我的答案操作即可。 - Alexander Shukaev

2
这种类型的运算符
bool operator> (const int &, const FOOD &) const; 

不能是成员。成员函数需要一个额外的、隐式参数,类型为FOOD*(可能带有cv限定符),因此上面的例子实际上需要三个参数。你需要将其变为非成员。

我认为最简单的方法是给你的类一个显式的int转换运算符。

explicit operator int() const { return foodID; }

同时注意,所有比较运算符都可以用一个单一的运算符来表达,例如 bool operator<(例如在std库的关联容器中使用了这种技术)。

如果我删除所有运算符重载,那么仅仅添加以下这行代码到结构体声明中: explicit operator int() const { return foodID; } 是否有效? - HellHarvest

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接