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
我理解为什么它无法编译。我想避免重载所有算术运算符,如+ =, - =,& =,| =等。反正是否要避免必须定义所有运算符?我很可能需要其中的大部分。
非常感谢!
答案 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
明确重载类的运算符将比依赖隐式转换更安全和可预测,隐式转换有时会产生奇怪的结果并编译错误。