如何表明某个类不支持某些运算符?

时间:2012-06-07 20:38:30

标签: c++ error-handling compiler-errors operator-overloading

我正在编写一个代表顺序尺度的类,但没有逻辑零点(例如时间)。 此比例应允许加法和减法(operator+operator+=,...)但不允许乘法。

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

我是否可以使用一种方法在编译时为此抛出错误?最简单的方法就是不要重载操作符operator*,...但是,添加比operator* is not know for class "time"更多的解释似乎是合适的。

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

5 个答案:

答案 0 :(得分:8)

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

未实施运营商时的最佳解决方案:不实施运营商。

答案 1 :(得分:4)

  

然而,当一个人超负荷时,我总觉得这是一个很好的做法   某个组的一个运算符(在本例中为数学运算符),一个   还应该超过属于该组的所有其他人。

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

的内容

答案 2 :(得分:2)

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

长版:粗略地说,具有“算术运算符”+-的集合的数学术语是(通常你不会除非运算符是可交换的,否则使用符号+作为组运算符,因此 Abelian组)。如果您将0移出集合,则具有乘法但不添加的集合也可以是一个组。加法和乘法在结构上相似 - 重要的区别在于乘法通常允许至少一个元素没有逆(0),而加法通常不会。

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

如果您的+-群组也有*,并且满足+*之间关系的某些条件,那么它就是 ring 字段如果除了附加标识之外的每个元素都有一个乘法逆(因此它有一个表现良好的/)。

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

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

持续时间与数字相似,但它们具有物理维度。将持续时间乘以无量纲数(2.4 * 3s == 7.2s)是有意义的,但很少将两个持续时间相乘,当你这样做时,结果不是持续时间,因为它的单位是秒平方。

答案 3 :(得分:0)

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

assert("Message");

答案 4 :(得分:0)

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