2013-08-23 19 views
2
union word{ 
    uint16_t value; 

    struct{ 
     uint8_t low; 
     uint8_t high; 
    }; 


    inline word(uint16_t value) noexcept 
     :value(value) 
    {} 


    inline word &operator=(uint16_t rhs) noexcept{ 
     value = rhs; 
     return *this; 
    } 

    inline operator uint16_t() const noexcept{ 
     return value; 
    } 
} 

我想定義一個小端的2字節類型,它很容易訪問低位和高位字節。另外,當調用任何算術運算符時,我希望「單詞」類型完全像uint16_t一樣行動。因此,我已經重載了uint16_t的類型轉換運算符。類型轉換過載聯合無過載+ =

但我遇到了一個小問題:

word w1 = 5; 
w1 = w1 + w1; //this works fine due to implicit conversion 
w1 += w1; //fails to compile. lhs will not implicitly convert 

我明白爲什麼它無法編譯。我想避免重載所有算術運算符,例如+ =, - =,& =,| =等。是否有避免必須定義所有運算符?我很可能需要他們中的大部分。

非常感謝!

回答

1

問題是這一行:

inline operator uint16_t() const noexcept{ 
    return value; 
} 

當你

w1 += w1; 

左手w1被隱式轉換爲uint16_t。但是,您實際上正在返回w1.value副本,作爲轉換的結果,它是臨時對象。並且您不允許分配給臨時對象。如果你神奇地可以,這些更改不會反映到w1.value,這是你不想要的。

解決您的問題,返回參考value代替,並進行轉換功能不const,你絕對會想value被修改。

inline operator uint16_t&() noexcept{ 
    return value; 
} 

Here is a live example表明該解決方案有效。


不過,我建議你閱讀了這個問題:Operator overloading

明確重載類的運營商將不是依賴於隱式轉換,這有時會產生怪異的結果和編譯錯誤更安全和可預見的。

相關問題