假设我们有以下代码:
class A {
uint32_t X;
uint32_t Y;
};
int main ()
{
A a;
uint64_t num = (uint64_t)a;
}
编译器给出错误:“无法从 A 转换为 uint64_t。未定义用户定义转换运算符。”
是预期的错误,如果是,为什么?
假设我们有以下代码:
class A {
uint32_t X;
uint32_t Y;
};
int main ()
{
A a;
uint64_t num = (uint64_t)a;
}
编译器给出错误:“无法从 A 转换为 uint64_t。未定义用户定义转换运算符。”
是预期的错误,如果是,为什么?
您需要将一个值的 32 位显式复制到 64 位值的高 32 位,将其他 32 位复制到 64 位值的低 32 位。
所有其他方法在技术上都是未定义的行为(尽管如果您足够了解您的实现细节,它们可以工作)。
class A
{
uint32_t X;
uint32_t Y;
uint64_t to64()
{
// convert X and Y to unsigned 64-bit ints
uint64_t x64 = X;
uint64_t y64 = Y;
// left-shift the 64-bit X 32 bits
x64 <<= 32;
// return the sum
return( x64 + y64 );
}
};
您可以使用更少的代码来完成它,但这会逐步显示您需要做的事情。
您尚未指定表示的“字节顺序”。如果你想x
成为高位词和y
低位词,你可以在你的类中添加一个强制转换运算符:
explicit operator uint64_t () const noexcept
{
return ((static_cast<uint64_t>(X) << 32) | Y);
}
A '(uint64_t) obj'
or (理想情况下)'static_cast<uint64_t>(obj)'
将调用此方法。explicit
防止它被隐式调用——这可能是我整天说的最愚蠢的事情——但它可以防止意外。如果您使用<cstdint>
和加分std::uint64_t
。
绝对未定义的行为,但尝试
uint64_t num = *reinterpret_cast<uint64_t *>(&a);