在没有重载+ =的情况下在联盟上重载Typecast

时间:2013-08-23 05:57:17

标签: c++ operator-overloading unions

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字节类型,很容易访问低字节和高字节。另外,我想在调用任何算术运算符时,“word”类型完全像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 个答案:

答案 0 :(得分: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; } 修改

{{1}}

Here is a live example显示解决方案有效。


但是,我建议您阅读此问题:Operator overloading

明确重载类的运算符将比依赖隐式转换更安全和可预测,隐式转换有时会产生奇怪的结果并编译错误。