运算符的奇怪行为> =重载 [英] Odd behavior with operator>= overloading

查看:129
本文介绍了运算符的奇怪行为> =重载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个奇怪的行为与操作符重载在C + +。我有一个类,我需要检查其内容是否大于或等于长双。我重载了> =运算符来做这个检查,我的声明如下:

I'm having a strange behavior with an operator overloading in C++. I have a class, and I need to check if its contents are greater or equal to a long double. I overloaded the >= operator to make this check, my declaration is as follows:

bool MyClass::operator>=(long double value) const;

我不得不说我对我的类有一个cast-to-long-只有在某些条件下才能工作。
现在,当我使用这个运算符时,编译器会抱怨使用operator> =,并且替代方法是:

I have to say that I also have a cast-to-long-double operator for my class, that works without exceptions only under certain conditions. Now, when I use this operator, the compiler complains that there's an ambiguous use of operator>= and the alternatives are:


  • Mine。

  • 内置 operator> =(long double,int)

  • Mine.
  • The built-in operator>=(long double, int).

现在,如何强制程序使用我的操作符?

Now, how do I force the program to use my operator?

推荐答案

p> 2015 update:或者,如果您想使用(double)obj 语法而不是 obj .to_double()语法,通过为该关键字添加前缀,使转换函数显式。您需要一个显式转换,然后为转换触发。就个人而言,我喜欢 .to_double 语法,除非转换为 bool ,因为在这种情况下,由 if(obj)即使它是 explicit ,并且比如果(obj.to_bool())在我看来。

2015 update: Or, if you want to keep conversion ability using the (double)obj syntax instead the obj.to_double() syntax, make the conversion function explicit by prefixing it with that keyword. You need an explicit cast then for the conversion to trigger. Personally, I prefer the .to_double syntax, unless the conversion would be to bool because in that case the conversion is used by if(obj) even if it is explicit, and that is considerably more readable than if(obj.to_bool()) in my opinion.

删除转换操作符。它会一直引起麻烦。具有

Drop the conversion operator. It will cause troubles all the way. Have a function like

to_double()

或者类似的,返回double值并调用该函数显式地获取一个double。

Or similar that returns the double value and call that function explicitly to get a double.

对于手头的问题,有这个问题:

For the problem at hand, there is this problem:

obj >= 10

内置运算符使用转换运算符long double()通过用户为类型定义的转换序列匹配第一个参数。但是你的函数通过从int到long double(积分到浮点转换)的标准转换序列匹配第二个参数。当有两个参数的转换时,总是含糊不清,但至少一个参数可以更好地转换,而其余的参数不会因为一个调用而转换得更差。在你的情况下,内置的一个更好地匹配第二个参数,但第一个更糟,但你的函数匹配第一个参数更好,但第二个更糟。

Consider that expression. The builtin operator matches the first argument by a user defined conversion sequence for your type using the conversion operator long double(). But your function matches the second argument by a standard conversion sequence from int to long double (integral to floating point conversion). It is always ambiguous when there are conversions for two arguments, but not at least one argument that can be converted better while the remaining arguments are not converted worse for one call. In your case, the builtin one matches the second argument better but the first worse, but your function matches the first argument better but the second worse.

这很奇怪,所以这里有一些例子(从char到int的转换称为促销,这比从char转换为int以外的其他转换更好转换):

It's confusing, so here are some examples (conversions from char to int are called promotions, which are better than conversions from char to something other than int, which is called a conversion):

void f(int, int);
void f(long, long);
f('a', 'a');

调用第一个版本。因为第一个的所有参数可以更好地转换。同样,下面仍然会调用第一个:

Calls the first version. Because all arguments for the first can be converted better. Equally, the following will still call the first:

void f(int, long);
void f(long, long);
f('a', 'a');

因为第一个可以更好地转换,第二个不会转换得更糟。但以下是不明确的:

Because the first can be converted better, and the second is not converted worse. But the following is ambiguous:

void f(char, long);
void f(int, char);
f('a', 'a'); // ambiguous

在这种情况下更有趣。第一个版本通过完全匹配接受第一个参数。第二个版本通过精确匹配接受第二个参数。但两个版本不接受他们的另一个论点,至少同样好。第一个版本需要对其第二个参数进行转换,而第二个版本需要对其参数进行升级。因此,即使促销优于转化,对第二个版本的调用也会失败。

It's more interesting in this case. The first version accepts the first argument by an exact match. The second version accepts the second argument by an exact match. But both versions do not accept their other argument at least equally well. The first version requires a conversion for its second argument, while the second version requires a promotion for its argument. So, even though a promotion is better than a conversion, the call to the second version fails.

它与上面的情况非常相似。即使标准转换序列(从int / float / double转换为long double)比用户定义的转换序列(从MyClass转换为long double)更好,但是不选择运算符版本,因为你的其他参数(long double)需要一个比内置操作符需要的参数(完全匹配)更糟的参数的转换。

It's very similar to your case above. Even though a standard conversion sequence (converting from int/float/double to long double) is better than a user-defined conversion sequence (converting from MyClass to long double), your operator version is not chosen, because your other parameter (long double) requires a conversion from the argument which is worse than what the builtin operator needs for that argument (perfect match).

过载分辨率是一个复杂的物质在C ++,所以一个人不可能记住它的所有微妙的规则。但是获得粗略的计划是非常可能的。我希望它能帮助你。

Overload resolution is a complex matter in C++, so one can impossibly remember all the subtle rules in it. But getting the rough plan is quite possible. I hope it helps you.

这篇关于运算符的奇怪行为> =重载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆