C++ 在C++;是否需要在两个方向上重载运算符==?

C++ 在C++;是否需要在两个方向上重载运算符==?,c++,operator-overloading,C++,Operator Overloading,假设我在一个班级工作: class Foo{ public: std:string name; /*...*/ }/*end Foo*/ 我为操作符== bool operator==(const Foo& fooObj, const std::string& strObj) { return (fooObj.name == strObj); } 我是否还需要反向重新实现相同的逻辑 bool operator==(const std::string&

假设我在一个班级工作:

class Foo{
public:
  std:string name;
  /*...*/
}/*end Foo*/
我为
操作符==

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);
}
(C++20及以后)

随着对C++20的接受,您不需要提供多个重载。该文件对标准进行了以下更改(除其他外):

[over.match.oper]

-[…]用于
=
运算符([expr.eq]),重写的候选运算符包括运算符
=
的所有成员、非成员和内置候选运算符,当使用该运算符在上下文中转换为bool时,重写的表达式
(x==y)
格式良好。对于等式运算符,重写的候选者还包括一个合成候选者,两个参数的顺序颠倒,用于每个成员、非成员和重写表达式为其
==
的运算符的内置候选者(y==x)当使用该操作符将上下文转换为bool时,格式良好。[ 注意:从成员候选者合成的候选者将其隐式对象参数作为第二个参数,因此第一个参数考虑隐式转换,而第二个参数不考虑隐式转换- 尾注 ] [……]

[…]如果通过重载解析为
!=
运算符选择重写的候选项,
x!=y
将被解释为
(y==x)?false:如果所选候选项是参数顺序相反的合成候选项,则为true
,或
(x==y)?false:true
否则,使用所选重写的
运算符==
候选。如果通过重载解析为
==
运算符选择重写的候选,则
x==y
被解释为
(y==x)?true:false
使用所选重写的
运算符==
候选

上面的意思是,不仅您不需要为运算符提供反转的操作数顺序,您还可以免费获得
!=
!此外,
运算符==
函数可以是成员,如果它有意义的话。尽管如上面第一段中的说明所述,它是成员或自由函数将影响隐式c所以你仍然需要记住这一点


(高达C++17)

如果要支持字符串位于左侧而
Foo
位于右侧的比较,则可以这样做。实现不会将参数重新排序为重载的
运算符==
,以使其正常工作

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

inline bool operator==(const std::string& objA, const Foo& objB) {
    return objB == objA; // Reuse previously defined operator
}

是的,就像许多其他语言一样,C++采用不同类型的两个对象之间的比较,根据命令的顺序,调用两个不同的比较运算符。


当然,你希望它们是一致的,不令人惊讶,所以第二个应该用第一个来定义。

因此理论上,人们可以为
Foo==String
String==Foo
实现不同的行为。是的,你可以。但你绝对不应该。@StoryTeller doe we get op!=免费使用这个as!(op==)或者应该同时在两个方向上实现吗?(期望答案是否定的)@hehe3301-恐怕所有您想要的重载都需要显式实现。尽管如此,主体可以是
!(lhs==rhs)
。这就是为什么
操作符
会产生如此多的刺激。因为它可以减少大量的样板文件。@hehe3301:您可以使用,它提供了要从中继承的类,并根据您提供的类填充操作符。例如,如果您从
等式
继承并提供
操作符==(T,U)
,它将提供
bool运算符==(常数U&,常数T&)
bool运算符!=(常数U&,常数T&)
,以及
bool运算符!=(常数T&,常数U&)
对你来说。顺便说一句,你将能够定义一个新的操作符,编译器将进行处理。它与
操作符
有关。我认为,更大的问题是
Foo
和字符串之间的相等概念是一个有效的概念还是一个固有的类别错误。一个事物与其名称、名称和名称不相等还有一种观点认为,这可能是让人们对指针和引用如此困惑的一部分。@StoryTeller-我一定错过了
操作符将对不同类型的参数重新排序的部分(你的第一条评论)-你能指出指定的部分吗?@TobySpeight-Re:“就像在其他语言中一样”:重载在不同语言中的工作方式完全不同,因此我认为这种笼统的说法没有帮助。