I'm learning about operator overloading in C++, and I see that == and != are simply some special functions which can be customized for user-defined types. My concern is, though, why are there two separate definitions needed? I thought that if a == b is true, then a != b is automatically false, and vice versa, and there is no other possibility, because, by definition, a != b is !(a == b). And I couldn't imagine any situation in which this wasn't true. But perhaps my imagination is limited or I am ignorant of something?

我知道我可以用一个定义另一个,但这不是我要问的。我也没有问通过值和单位来比较对象之间的区别。或者两个对象是否可以同时相等和不相等(这绝对不是一个选项!这些事情是相互排斥的)。我想问的是:

有没有可能在这种情况下,问两个对象是否相等的问题是有意义的,但问它们不相等的问题是没有意义的?(无论是从用户的角度,还是从实现者的角度)

如果没有这种可能性,那么究竟为什么c++将这两个操作符定义为两个不同的函数呢?


当前回答

如果==和!=操作符实际上并不意味着相等,就像<<和>>流操作符并不意味着位移位一样。如果你把这些符号当作其他概念来对待,它们就不必相互排斥。

就相等而言,如果您的用例保证将对象视为不可比较的,那么每次比较都应该返回false(或者如果操作符返回非bool类型,则返回不可比较的结果类型),那么这样做是有意义的。我想不出一个具体的情况,这将是必要的,但我可以看到它是足够合理的。

其他回答

当a == b返回bool类型以外的值时,您不会希望语言自动将a != b重写为!(a == b)。有几个原因可以让它这样做。

您可能有表达式构建器对象,其中a == b不会也不打算执行任何比较,而只是构建一些表示a == b的表达式节点。

你可能有惰性求值,其中a == b不会也不打算直接执行任何比较,而是返回某种惰性<bool>,可以在以后的某个时间隐式或显式地转换为bool来实际执行比较。可能与表达式构建器对象结合使用,以便在求值之前完成表达式优化。

你可能有一些自定义的可选<T>模板类,其中给定可选变量T和u,你想允许T == u,但让它返回可选<bool>。

可能还有我没想到的事。即使在这些例子中,操作a == b和a != b都是有意义的,但a != b与!(a == b)不是一回事,因此需要单独的定义。

enum BoolPlus {
    kFalse = 0,
    kTrue = 1,
    kFileNotFound = -1
}

BoolPlus operator==(File& other);
BoolPlus operator!=(File& other);

我不能证明这个操作符重载是正确的,但在上面的例子中,不可能定义操作符!作为运算符==的“对立面”。

也许是一个不可比较的规则,其中a != b为假,a == b为假,就像一个无状态位。

if( !(a == b || a != b) ){
    // Stateless
}

最后,使用这些操作符检查表达式a == b或a != b是否返回布尔值(true或false)。这些表达式在比较后返回一个布尔值,而不是互斥的。

有没有可能的情况是问关于二的问题 对象相等是有意义的,但是问它们不相等 相等没有意义吗?(无论是从用户的角度,还是从 实现者的角度)

这只是个人观点。也许不是。但是语言的设计者并不是无所不知的,他们决定不限制那些可能想出有意义的情况的人(至少对他们来说)。