0

我正在编写一个表示序数比例的类,但没有逻辑零点(例如时间)。这个比例应该允许加减法(operator+, operator+=, ...),但不允许乘法。

然而,我一直认为这是一种很好的做法,即当重载某个组的一个运算符(在本例中为数学运算符)时,还应该重载属于该组的所有其他运算符。在这种情况下,这意味着我还需要重载乘法和除法运算符,因为如果用户可以使用A+B他可能希望能够使用其他运算符。

有没有一种方法可以用来在编译器时为此抛出错误?最简单的方法是 no 重载运算符operator*,......但添加比operator* is not know for class "time".

或者这是我真的不应该关心的事情(RTFM 用户)?

4

5 回答 5

8

实现一个运算符只是为了发出未实现的信号似乎是做作的。如果有的话,您可以将其定义为private成员函数,并static_assert在其中放置一个如果有人(可能是朋友)尝试使用它时显示编译器错误。

未实施运算符时的最佳解决方案:不实施它。

于 2012-06-07T20:41:23.727 回答
4

然而,我一直认为这是一种很好的做法,即当重载某个组的一个运算符(在本例中为数学运算符)时,还应该重载属于该组的所有其他运算符。

错误的。唯一的组是++=- 然后可能 -是和-=。“算术运算符”一般不是一个组。考虑类似的东西std::string

于 2012-06-07T20:44:02.870 回答
2

简短版:有些数学结构有加法但没有乘法,所以不用担心。重载对您所表示的数学结构有意义的运算符。如果有人试图将两次相乘,那么这个错误no match for operator* in ...对任何 C++ 程序员都应该是有意义的。如果您认为他们真的会对为什么不能乘以两次感到困惑,您可以在文档中进行扩展。我认为编译器的工作并不是知道为什么运算符对给定的类没有意义,并在错误消息中表达出来。

长版:粗略地说,具有“算术运算符”+并且-是一个的集合的数学术语(通常您不会使用该符号+表示组运算符,除非该运算符是可交换的,因此是Abelian group)。一个有乘法但没有加法的集合也可以是一个组,只要你离开0集合。加法和乘法在结构上相似——重要的区别是乘法通常允许至少一个元素没有逆 ( 0),而加法通常不允许。

+有时也用作符号,如自然数中的加法、序列连接,甚至是集合并集,其中元素通常没有逆。在那种情况下,你甚至没有一个组,只有一个二进制函数,你不会定义 unary -,你也可能不会定义 binary -。在这种情况下,可以说+是运算符的错误选择,但为时已晚std::string

如果你的组也有+和,并且满足关于和之间关系的某些条件,那么它就是一个,或者如果除了加法恒等元之外的每个元素都有一个乘法逆元(因此它有一个良好的行为) ,那么它就是一个域。-*+*/

关于时间,考虑两个不同的概念通​​常很有用:绝对时间和持续时间。您可以将两个持续时间相加(给出一个持续时间),或者一个绝对时间和一个持续时间(给出一个绝对时间),但是将两个绝对时间相加是没有意义的(什么是“上周一加下周四”?)。

这种行为类似于在指针(代替绝对时间)和整数(代替持续时间)上定义的运算符,这并非完全巧合。你可以做(char*)0 + 0,但你做不到(char*)0 + (char*)0。所以绝对时间没有添加剂operator+(abstime, abstime),但可以有operator+(abstime, duration)

Durations are like numbers, but they have a physical dimension. It makes sense to multiply a duration by a dimensionless number (2.4 * 3s == 7.2s), but only rarely to multiply together two durations, and when you do the result is not a duration since its units are seconds-squared.

于 2012-06-07T22:36:20.783 回答
0

只需声明重载的运算符,但不要实现它。在编译时,链接器会大惊小怪。

于 2012-06-07T20:43:30.167 回答
-1

编辑:我注意到您希望在使用它时调用它,那么最好不要实现它,或者可能使用 assert 命令来解决运行时错误。

assert("Message");
于 2012-06-07T20:42:19.277 回答