[英]more than one operator matches these operands
假設我們有下一個代碼:
struct int64
{
long long value;
int64() : value(0) {}
int64(signed char i8) : value(i8) {}
int64(unsigned char u8) : value(u8) {}
int64(short i16) : value(i16) {}
int64(unsigned short u16) : value(u16) {}
int64(int i32) : value(i32) {}
int64(unsigned u32) : value(u32) {}
int64(long long i64) : value(i64) {}
int64(unsigned long long u64) : value(u64) {}
int64(const int64& i64) : value(i64.value) {}
int64& operator+=(const int64& rhs) { return value += rhs.value, *this; }
int64& operator-=(const int64& rhs) { return value -= rhs.value, *this; }
friend int64 operator+(const int64& lhs, const int64& rhs) { return int64(lhs) += rhs; }
friend int64 operator-(const int64& lhs, const int64& rhs) { return int64(lhs) -= rhs; }
operator char() const { return (char)value; }
operator short() const { return (short)value; }
operator int() const { return (int)value; }
operator long long() const { return value; }
};
編譯此代碼時:
int64 q = 500;
int64 m = q + 1024;
發生錯誤是因為有4個相似的轉換可用於1024
,而q
可轉換為整數類型,為解決此問題,我從int64
刪除了operator XX
並添加了以下代碼:
template <typename n>
operator n() const { return (n)value; }
現在我可以執行以下代碼:
int64 q = 500;
int64 m = q + 1024;
short r = q;
模板定義適用於Visual C++
和GCC
編譯器,但適用於Intel C++
編譯器。
如何編寫適用於那些編譯器的轉換運算符?
您應該為所支持的所有類型編寫operator+
定義:
int64 operator+(int num) {
return int64(value + num);
}
int64 operator+(short num) {
...
}
...
您要向int64
添加一個int
並將結果分配給int64
但它沒有副本構造函數,因此它將其轉換為某種整數類型,並嘗試對所有這些轉換運算符和構造函數進行一些奇怪處理。
從C ++ 11(當問這個問題時剛剛批准)開始,您可以將轉換標記為explicit
:
struct int64
{
// ...
explicit operator char() const { return (char)value; }
explicit operator short() const { return (short)value; }
explicit operator int() const { return (int)value; }
explicit operator long long() const { return value; }
};
這應該可以在所有主要編譯器的最新版本中使用(我測試過的所有編譯器都具有足夠的C ++ 11支持)。 您也可以根據需要將其應用於模板化轉換運算符,盡管我更喜歡四種非模板化轉換(此外,這使我嘗試過的ICC版本崩潰了!):
struct int64
{
// ...
template <typename n>
explicit operator n() const { return static_cast<n>(value); }
};
但是,這意味着您不能做short r = q;
。 對我來說,這是一件好事,因為縮小的轉化范圍實際上應該是
short r = static_cast<short>(q);
這里的問題是,如果您既提供內置類型的構造函數,又提供相同類型的轉換運算符,然后同時具有兩種類型的表達式,則C ++不能真正確定應該采用哪種方式。 因此,“ myInt64Variable + 1024”可能意味着通過轉換到int運算符來實現“(int)myInt64Variable + 1024)”,或者通過構造函數來實現“ myInt64Variable +(int64)1024”。
以我的經驗,處理此問題的最佳方法是不提供轉換運算符,或者,如果必須要使用轉換運算符,則不要使用toInt()函數或類似函數。 從您的自定義類型到內置類型的任何轉換都將是有損的,否則為什么要自定義類型呢?讓人們注意到他們何時執行有損轉換是一件好事。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.