Разве я не могу типизировать класс размером 8 байтов к uint64_t?

Предположим, у нас есть код ниже:

class A {
uint32_t X;
uint32_t Y;
};

int main ()
{
A a;
uint64_t num  = (uint64_t)a;
}

Компилятор выдает ошибку: «Не удается преобразовать из A в uint64_t. Пользователь не определил оператор преобразования, определенный».

Ожидается ли ошибка и если да, то почему?

2

Решение

Вам необходимо явно скопировать 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 );
}
};

Вы можете сделать это с гораздо меньшим количеством кода, но это показывает, что вам нужно делать шаг за шагом.

3

Другие решения

Вы не указали «порядковый номер» своего представления. Если ты хочешь 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,

0

Определенно неопределенное поведение, но попробуйте

uint64_t num  = *reinterpret_cast<uint64_t *>(&a);
-2
По вопросам рекламы [email protected]