【发布时间】:2011-07-05 05:21:29
【问题描述】:
重载 &&, || 是不是一个坏主意或逗号运算符,为什么?
【问题讨论】:
-
这感觉像是一道期末考试题 ;)
标签: c++ operators operator-overloading logical-operators
重载 &&, || 是不是一个坏主意或逗号运算符,为什么?
【问题讨论】:
标签: c++ operators operator-overloading logical-operators
【讨论】:
除非你的类代表一些逻辑实体,否则这是个坏主意,因为重载的运算符会迷失方向,并可能导致代码中出现新的错误。
【讨论】:
我会说这取决于您的重载在做什么。例如,&& 和 ||预计将作为逻辑条件工作,因此如果您的重载语义以某种方式工作,它们可能会混淆其他人(甚至您自己,如果您有一段时间不使用它们而忘记了它们的作用)。考虑一下,如果您不知道运算符是如何被重载的,并且只使用普通方法会更清楚,那么您希望运算符做什么。
【讨论】:
我不会超载operator&& 或operator||。即使您定义了一个产生布尔代数的类(例如有限集),重载operator& 和operator| 可能是更好的选择。
原因是 C++ 程序员希望 operator&& 和 operator|| 有特殊的语义:它们是短路,即如果没有必要,不计算它们的右手参数。您无法通过重载获得此行为,因为您将定义一个函数。
重载operator, 已经在例如Boost.Assign 库。这也是我所知道的唯一一个重载的例子,我什至从来没有考虑过自己重载它。你最好有一个非常具体的用例,没有其他运算符适合。
【讨论】:
operator bool())提供一个转换为布尔的运算符似乎更好?
operator bool,这样您就可以免费短路。如果 operator& 和 operator| 具有布尔代数语义,则定义 operator|,就像有限集一样(其中交集是 &,并集是 |)。
正如其他人所说,缺少惰性求值是避免重载逻辑运算符的主要原因。
但是,超载它们有一个很好的理由:Expression templates。 Boost.Lambda 库可以做到这一点,而且非常有用!
【讨论】:
这通常是个坏主意:这三个运算符具有排序效果,当您重载它们时就会丢失。失去这种排序效果可能会导致那些没想到会丢失的人(即奇怪的错误)。
在某些情况下,模板表达式可以保持排序效果,在这些情况下,我认为重载它们没有问题。
operator, 的重载我知道还有另一个问题:它们的工作方式使得明显的操作链不是真实的。通常,它们会在没有区别的情况下用于上下文,但一旦出现在蓝月亮中,那就是奇怪错误的另一个来源。
【讨论】:
您不应该以令人惊讶的方式重载任何运算符。 :-)
如果您能以一种有意义的方式(不仅对您)这样做,那么这样做是可以的。
正如其他人所说,逻辑运算符的特殊之处在于它们具有惰性求值的效果。所以你的重载可能应该保留这种惰性效果,就像表达式模板一样,或者只在人们不期望这种效果的地方使用。
【讨论】: