在C ++中,您是否需要在两个方向上重载operator ==?

时间:2018-11-14 12:21:19

标签: c++ operator-overloading

说我正在上课:

class Foo{
public:
  std:string name;
  /*...*/
}/*end Foo*/

我为operator==

提供了重载
bool operator==(const Foo& fooObj, const std::string& strObj) {
    return (fooObj.name == strObj);
}

我还需要反向重新实现相同的逻辑吗?

bool operator==(const std::string& strObj, const Foo& fooObj) {
    return (strObj == fooObj.name);
}

2 个答案:

答案 0 :(得分:75)

(从C ++ 20开始)

随着p1185被C ++ 20接受,您无需提供多个重载。论文对标准进行了其他更改:

  

[over.match.oper]

     

3.4-[...]对于!=运算符([expr.eq]),重写的候选者包括该运算符{的所有成员,非成员和内置候选者{ {1}},当使用该运算符==上下文转换为bool时,重写表达式(x == y)的格式正确。对于相等运算符,重写的候选还包括针对每个成员,非成员和运算子==的内置候选的合成候选,其中两个参数的顺序相反。使用该运算符==上下文转换为bool时,{1}}的格式正确。 [注:从成员候选者合成的候选者具有其隐式对象参数作为第二个参数,因此,对于第一个参数(而不是第二个参数)考虑隐式转换。 —尾注] [...]

     

8 [...]如果通过重载决议为(y == x)运算符选择了重写的候选项,则如果所选的候选项是==,则!=被解释为x != y。使用选定的重写的(y == x) ? false : true候选者,按相反的参数顺序合成候选者,否则返回(x == y) ? false : true。如果通过重载决议为operator==运算符选择了重写的候选者,则使用所选的重写的==候选者将x == y解释为(y == x) ? true : false

上面的意思是,不仅您不需要向操作员提供相反的操作数顺序,而且还免费获得operator==!此外,!=函数可以是一个成员(如果有意义)。尽管如上面第一段所述,它是成员或自由函数会影响隐式转换,所以您仍然需要牢记这一点。


(最多C ++ 17)

如果您想支持字符串在左侧而operator==在右侧的比较,则可以这样做。实现不会将参数重排到重载的Foo上才能使其正常工作。

但是,您可以避免重复实现的逻辑。假设您的操作员的行为应符合预期:

operator==

答案 1 :(得分:6)

是的,你知道。就像在许多其他语言中一样,C ++也具有优势,并且两个不同类型的对象之间的比较将导致根据顺序调用两个不同的比较运算符。

当然,您希望它们保持一致且毫不奇怪,因此,第二个应该以第一个定义。