2015 更新:或者,如果您想使用(double)obj
语法而不是语法来保持转换能力,请通过在其前面加上该关键字来obj.to_double()
创建转换功能。explicit
然后您需要显式转换才能触发转换。就个人而言,我更喜欢这种.to_double
语法,除非转换是 to,bool
因为在这种情况下,if(obj)
即使它是explicit
,也会使用转换,这比if(obj.to_bool())
我认为的可读性要高得多。
删除转换运算符。一路上都会惹来麻烦。有一个像
to_double()
或类似的返回双精度值并显式调用该函数以获得双精度值。
对于手头的问题,有这个问题:
obj >= 10
考虑一下这个表达式。内置运算符使用转换运算符 long double() 通过用户定义的类型转换序列匹配第一个参数。但是您的函数通过从 int 到 long double(整数到浮点转换)的标准转换序列匹配第二个参数。当有两个参数的转换时总是模棱两可的,但至少有一个参数可以转换得更好,而其余的参数在一次调用中不会转换得更糟。在您的情况下,内置函数更好地匹配第二个参数,但第一个更差,但您的函数更好地匹配第一个参数,但第二个更差。
这很令人困惑,所以这里有一些示例(从 char 到 int 的转换称为提升,这比从 char 到非 int 的转换更好,这称为转换):
void f(int, int);
void f(long, long);
f('a', 'a');
调用第一个版本。因为第一个参数的所有参数都可以更好地转换。同样,以下仍将调用第一个:
void f(int, long);
void f(long, long);
f('a', 'a');
因为第一个可以转换得更好,而第二个不能转换得更差。但以下是模棱两可的:
void f(char, long);
void f(int, char);
f('a', 'a'); // ambiguous
在这种情况下更有趣。第一个版本通过完全匹配接受第一个参数。第二个版本通过完全匹配接受第二个参数。但是两个版本至少同样好地不接受他们的另一个论点。第一个版本需要对其第二个参数进行转换,而第二个版本需要对其参数进行提升。因此,即使促销比转换更好,对第二个版本的调用也会失败。
这与您上面的情况非常相似。即使标准转换序列(从 int/float/double 转换为 long double)比用户定义的转换序列(从 MyClass 转换为 long double)更好,但不会选择您的运算符版本,因为您的其他参数(long double ) 需要从参数进行转换,这比内置运算符对该参数的需要更差(完美匹配)。
重载解析在 C++ 中是一件复杂的事情,因此人们不可能记住其中的所有微妙规则。但是得到粗略的计划是很有可能的。我希望它对你有帮助。