簡體   English   中英

多個運算符與這些操作數匹配

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM