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 字节类型,以便轻松访问低字节和高字节。此外,我希望“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

我明白为什么它无法编译。我想避免重载所有算术运算符,例如 +=、-=、&=、|= 等。有没有办法避免必须定义所有运算符?我很可能需要其中的大部分。

非常感谢!

4

1 回答 1

1

问题在于这一行:

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

当你这样做

w1 += w1;

左手w1被隐式转换为 a uint16_t。但是,您实际上是在返回一个副本w1.value作为转换的结果,它是一个临时对象。而且您不允许分配给临时对象。如果你能神奇地做到,这些变化不会反映到w1.value你不想要的东西上。

要解决您的问题,请改为返回一个引用value并使转换函数 not const,因为您绝对希望value可以修改。

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

这是一个现场示例,显示该解决方案有效。


但是,我建议您阅读这个问题:运算符重载

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

于 2013-08-23T06:13:03.963 回答