Этот вопрос основан на:
Сдвиг с 64-битным int
Происхождение вопроса — я определяю enum
, в котором представлены разные маски.
И нужно сделать &
переменной с enum
(маска) после этого сдвига результат вправо.
поскольку enum
тип всегда int
переменная была определена также как int
Но как вы можете видеть, есть проблема смещения правых отрицательных чисел.
что можно сделать, чтобы решить это?
Во-первых, enum
типа не всегда int
; в C ++ 11 вы можете
даже заставить его быть неподписанным типом. И во-вторых, даже когда
базовый тип int
Вы можете (и должны) свободно бросать
и из unsigned
без реального риска. Вы можете, например, перегрузить
operator&
Таким образом:
MyEnum
operator&( MyEnum lhs, MyEnum rhs )
{
return static_cast<MyEnum>(
static_cast<unsigned>( lhs) & static_cast<unsigned>( rhs ) );
}
Для извлечения полей, которые могут быть где-то посередине:
int
getFieldX( MyEnum values )
{
return static_cast<unsigned>(values & fieldXMask) >> fieldXOffset;
}
Это обеспечит правильное поведение (и как только значение без знака
было смещено, оно должно быть преобразовано в int
без потери
значение).
Я предлагаю вам статическое приведение значения перечисления к unsigned long long
до сдвига. Я думаю, что это самый безопасный вариант, который вы можете использовать.
Вы можете сначала выполнить сдвиг, затем И против смещенной маски, чтобы обойти это.