Предположим, у нас есть код ниже:
class A {
uint32_t X;
uint32_t Y;
};
int main ()
{
A a;
uint64_t num = (uint64_t)a;
}
Компилятор выдает ошибку: «Не удается преобразовать из A в uint64_t. Пользователь не определил оператор преобразования, определенный».
Ожидается ли ошибка и если да, то почему?
Вам необходимо явно скопировать 32 бита одного значения в верхние 32 бита 64-битного значения, а остальные 32 бита — в нижние 32 бита 64-битного значения.
Все остальные методы являются технически неопределенным поведением (хотя, если вы знать детали вашей реализации достаточно хорошо, они могут работать).
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);
}
'(uint64_t) obj'
или (в идеале) 'static_cast<uint64_t>(obj)'
вызову этот метод. explicit
препятствует тому, чтобы это вызывалось неявно — что является, вероятно, самой глупой вещью, которую я говорил весь день — но это предотвращает сюрпризы. Дополнительные очки, если вы используете <cstdint>
а также std::uint64_t
,
Определенно неопределенное поведение, но попробуйте
uint64_t num = *reinterpret_cast<uint64_t *>(&a);