你会考虑这个糟糕设计的证据吗?
//FooType and BarType not in the same hierarchy
bool operator==(const FooType &, const BarType &);
bool operator<(const FooType &, const BarType &);
例如,如果FooType
是double
测量自纪元以来的秒数而BarType
是三个整数(年,月和日)的元组,提供UTC日期,则比较如上“有意义”。
你见过这种类型间的比较吗?他们在C ++社区中不受欢迎吗?
答案 0 :(得分:4)
首先,使用自由函数而不是成员函数没有任何问题,事实上它是推荐的做法。见Scott Meyer的How Non-Member Functions Improve Encapsulation。您可能希望在两个方向上提供比较:
bool operator==(const FooType &, const BarType &);
bool operator==(const BarType &, const FooType &);
其次,如果比较有意义,提供这些比较是完全可以接受的。例如,标准库允许您将std::complex
值与浮点值进行比较,但不要小于。{/ p>
你要避免的一件事是比较没有意义。在您的示例中,其中一个时间值是double,这意味着一旦您考虑标准促销,任何浮点或整数值都会进行比较。这可能比您预期的要多,因为无法确定任何特定值是否代表时间。丢失类型检查意味着可能存在意外错误。
答案 1 :(得分:3)
个人愿景和经验
我个人并不鄙视不同类型之间的比较。我甚至鼓励它,因为它可以提高代码的可读性;做你正在做的事情似乎更合乎逻辑。在基本数字类型之外,也许是一个字符串和一个字符,我发现很难给你一个逻辑的类型内比较,我不记得见过很多。我遇到了很多像这样使用的算术运算符。
如何使用
你应该小心你正在做的事情,因为某种原因它们几乎没有被使用。如果您提供用于比较两种不同类型的函数,则结果应该是逻辑的以及用户直观期望的结果。为它编写好的文档也是可取的。 Mark Ransom已经说过了,但如果用户可以在两个方向进行比较,那就很好了。如果您认为您的比较对于操作员来说不够清楚,您应该考虑使用命名函数。如果您的操作员可以有多种含义,这也是一个非常好的解决方案。
可能出现什么问题
您无法完全控制用户对您所写内容的处理方式。 tletnes给出了一个很好的例子,比较了两个整数,但结果没有意义。与此相反,两种不同类型的比较可能是非常正确的。可以很好地比较表示秒的浮点数和整数。
算术运算符
在逻辑旁边,我想展示一个带算术运算符的内部类型示例。在讨论类型内使用时,算术运算符非常类似于逻辑运算符。
假设您有一个运算符+用于二维向量和一个正方形。这是做什么的?用户可能认为它缩放了正方形,但另一个用户确信它会翻译!这些问题对您的用户来说非常令人沮丧。您可以通过提供良好的文档来解决这个问题,但我个人更喜欢的是具体命名的函数,如Translate。
<强>结论强>
内部类型逻辑运算符可能很有用并且可以生成干净的代码,但是错误的使用会使一切变得更加复杂。
答案 2 :(得分:1)
好的设计会决定你只应该比较兼容意义的值。通常类型是意义的好线索,但不是最后一个词,实际上在很多情况下,同一类型的两个值可能具有不相容的含义,例如以下两个整数:
int seconds = 3 //seconds
int length = 2; //square inches
if(seconds >= length){
//what does this mean?
}
在这个例子中,我们将长度与秒进行比较,但是两者之间没有一个令人感动的关系。
int test_duration = 3 //minutes
float elapsed_time = 2.5; //seconds
if((test_duration * 60) >= elapsed_time ){
//tes is done
}
在这个例子中,我们比较了不同类型(和单位)的两个值,但是它们的含义仍然是兼容的(它们都代表时间)所以(假设这两个存储的原因很好(例如易于使用) API等)这是一个很好的设计。
答案 3 :(得分:0)
根据Stepanov的规则(请参阅编程元素),平等与复制(构造和分配)(以及不平等)紧密相关。
因此,如果对象表示相等的值,则继续进行操作,使它们相等,但同时考虑这四个操作(相等,[复制]构造,赋值和不相等)。 通过扩展,还可以从不同类型来回转换(在另一侧进行铸造操作或构造)。
它也隐式地连接到可以应用于这些值的任何“常规”函数。 Stepanov将两个值定义为相等(如果对其应用任何(常规)函数得出相等的结果)。
我还要说的是,即使您可以比较两个相等的对象并彼此构造一个对象,但是如果可以应用于这两个对象的一组通用函数(无论是否通用)不是相关集合,或者它们的结果通常是收益如果值不相等,则比较不同类型的对象几乎没有价值。 最糟糕的是,如果其中一种类型的功能根本比另一种类型的功能更多,该怎么办?可以保持反射力吗?
最后,如果比较两个对象为 O(N ^ 2)或更高(其中 N 是对象的“大小”某种程度的对象),那么可以理解,比较对象根本没有任何价值。 (请参阅约翰·拉科斯的演讲https://www.youtube.com/watch?v=W3xI1HJUy7Q)
因此,正如您所看到的,它不只是提出一个比较标准来填充[key] : value
的正文,或者这是否是一个好习惯,还仅仅是个开始。
平等是如此基础,以至渗入所有程序的含义。