[英]Odd behavior with operator>= overloading
我在C ++中有一個運算符重載的奇怪行為。 我有一個課程,我需要檢查其內容是否大於或等於一個長整數。 我重載了> =運算符以進行此檢查,我的聲明如下:
bool MyClass::operator>=(long double value) const;
我必須說,我的班級也有一個強制轉換為雙精度雙精度運算符,該運算符僅在特定條件下才能正常工作。 現在,當我使用該運算符時,編譯器會抱怨運算符> =的使用模棱兩可,替代方法是:
operator>=(long double, int)
。 現在,如何強制程序使用我的運算符?
2015年更新:或者,如果您想使用(double)obj
語法而不是obj.to_double()
語法保持轉換能力,請在該轉換函數前添加該關鍵字作為前綴來使其explicit
。 您需要顯式強制轉換,然后才能觸發轉換。 就我個人而言,我更喜歡.to_double
語法,除非將轉換轉換為bool
因為在那種情況下,即使if if(obj)
是explicit
,轉換也被if(obj)
使用,並且比if(obj.to_bool())
更具可讀性。在我看來。
刪除轉換運算符。 它將一直引起麻煩。 具有像
to_double()
或類似的返回double值並顯式調用該函數以獲取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 ++中的一件事,因此不可能記住其中的所有微妙規則。 但是,制定粗略的計划是完全可能的。 我希望它對你有所幫助。
通過有效地說明對double
的隱式轉換,您可以有效地說明這一點,我的類等效於double
,因此,您不必在意是否使用了double
的內置運算符> =。 如果您確實關心的話,那么您的類實際上就不等同於double
並且您應該考慮不提供對double
的隱式轉換,而應提供顯式的 GetAsDouble或ConvertToDouble成員函數。
您目前不清楚的原因是,對於表達式t >= d
,其中t
是類的實例,而d
是雙精度型,編譯器總是必須提供左側或右側的轉換。如此一面手的表情確實是am昧的。 要么調用t
的operator double
,然后使用針對double
s的內置運算符> =,要么必須將d提升為long double
然后使用成員運算符> =。
編輯,您已經更新了問題,建議您將轉換為long double,並將比較與int進行比較。 在這種情況下,最后一段應為:
您目前不清楚的原因是,對於表達式t >= d
,其中t
是類的實例,而d
是int
,編譯器始終必須提供左側或右側的轉換。如此一面手的表情確實是am昧的。 要么調用t
的operator long double
,然后使用內置運算符> =來表示long double
和int
,要么必須將d提升為long double
並使用成員運算符> =。
我假設您正在與文字int
進行比較,而不是long double
int
:
MyClass o;
if (o >= 42)
{
// ...
}
如果是這樣的話,兩種選擇都一樣好/復雜。
使用operator long double()
:
MyClass::operator long double()
operator>=(long double, int)
使用您的MyClass::operator>=(long double)
:
int
轉換為long double
MyClass::operator>=(long double)
您的聲明中有long double
。 嘗試將其更改為double
。
看起來您已經定義了:
bool class::operator>=(long double value) { return value >= classValue; }
而且您不見了:
bool class::operator>=(double value) { return value >= classValue; }
bool class::operator>=(int value) { return value >= classValue; }
因此,編譯器無法確定轉換方式。 (模棱兩可。)
模板化的函數(或方法)也許會有所幫助?
當心a> = b調用與b> = a不同的方法的情況 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.