重载逻辑运算符被认为是不良实践吗?

14

重载 &&、|| 或逗号运算符是个不好的主意吗?为什么?


6
这感觉就像是一道期末考试题目 ;) - defbyte
7个回答

15

我不建议过度使用operator&&operator||。即使您定义了一个产生布尔代数的类(例如有限集合),重载operator&operator|可能是更好的选择。

原因是C++程序员期望 operator&&operator||具有特殊语义:它们是短路的,也就是说如果不必要则不会评估其右侧参数。通过重载无法实现此行为,因为这将定义一个函数。

在例如Boost.Assign库中已经重载了operator,。这也是我知道的唯一的重载示例,我甚至从未考虑过自己进行重载。最好在没有其他运算符适用的情况下使用非常特定的用例。


好的观点。因此,在这种情况下,提供一个转换为布尔值的运算符(operator bool())似乎更好? - davka
@davka:如果你的类具有布尔逻辑语义,那么定义operator bool可以为你提供免费的短路。如果它具有布尔代数语义,例如有限集合(其中交集是&,并集是|),则定义operator&operator | - Fred Foo
@larsmans:非常抱歉,是一次意外的点击。我不得不“编辑”你的答案以删除它(我删除了一个空白行)。 - rubenvb
2
@davka:关于bool转换的问题...不要这样做!请参考http://www.artima.com/cppsource/safebool.html,主要问题是bool可以提升为整数。最好定义一个转换运算符到成员函数指针。 - Matthieu M.

4

在C++中重载逻辑运算符时,必须对操作数进行评估,这与内置类型的短路方式通常不同。

请查看下面的链接。


3
通常情况下,重载这三个运算符是不明智的,因为它们具有一种顺序效应,而当你重载它们时,这种顺序效应会丢失。如果没有预料到这种情况,那么就可能会导致意想不到的问题。对于模板表达式存在一些情况可以保留这种顺序效应,在这些情况下,我认为重载这些运算符没有任何问题。
我所知道的operator,的重载还存在另一个问题:它们的工作方式使得表面上的操作链不是真正的操作链。通常情况下,它们用在一些上下文中时并没有什么区别,但是偶尔也会成为引发奇怪错误的源头之一。

3

不应该以令人惊讶的方式重载任何运算符。:-)

如果你能以有意义的方式完成它(不仅对你自己),那就可以这样做。

像其他人所说,逻辑运算符是特殊的,因为它们具有惰性求值的效果。因此,你的重载应该保留这种惰性效果,例如使用表达式模板,或者只在人们不期望这种效果的地方使用。


2

我认为这取决于你的重载函数是做什么的。例如,&&和||预期将作为逻辑条件工作,因此如果您的重载语义有所不同,则可能会使其他人困惑(甚至是您自己,如果您不使用它们一段时间并忘记了它们的功能)。考虑一下,如果你不知道它们被重载后会执行什么操作,是否更清晰地使用普通方法。


2

正如其他人所说,缺乏惰性求值是避免重载逻辑运算符的主要原因。

然而,有一个非常好的理由来重载它们:表达式模板。Boost.Lambda库就是这样做的,它非常有用!


0

除非您的类表示某些逻辑实体,否则重载运算符是一个不好的想法,因为它们会使人迷惑并可能在代码中引入新的错误。


即便您定义"逻辑实体"(布尔代数),其他运算符也更加适合。 - Fred Foo

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