Есть ли у этого приведения C ++ к enum проблемы? - PullRequest
4 голосов
/ 14 января 2011

Учитывая следующий код:

enum Options
{
    Surf     = 0x01,
    Out      = 0x02
};

Options all = (Options) ( Surf | Out);
  1. Есть ли проблемы у этого кастинга?
  2. Если этот кастинг имеет смысл, то почему?Исходя из моего понимания, параметры определяют только две переменные.Какое значение имеет значение 0x03?

Ответы [ 5 ]

7 голосов
/ 15 января 2011

Есть ли у этого кастинга проблемы?

номер

Если этот кастинг имеет смысл, то почему? Исходя из моего понимания, Options определяет только две переменные, как значение 0x03 имеет смысл?

Тип перечисления Options имеет два именованных перечислителя, но диапазон значений, которые он представляет, достаточно велик, чтобы его можно было использовать в качестве битового поля, содержащего каждый из перечислителей.

Вкратце: да, допустимо и четко определено использование перечисления для битового поля, подобного этому.

Как указано в комментариях к этому ответу, формальный язык, разрешающий это, можно найти в Стандарте C ++ (C ++ 03 7.2 / 6):

Для перечисления, где e min - наименьший перечислитель, а e max - наибольший, значения перечисления значения базового типа в диапазоне b min до b max , где b min и b max являются, соответственно, наименьшим и наибольшим значениями наименьшего битового поля, которое может хранить e min и e max .

Можно определить перечисление, значения которого не определены ни одним из перечислителей.

Есть некоторые споры относительно того, является ли это хорошим стилем. Конечно, можно утверждать, что часто предполагается, что объект перечисления может хранить только один из своих перечислителей, поэтому подобный код может быть запутанным и подверженным ошибкам.

С другой стороны, я бы сказал, что обычно вполне очевидно, когда перечисление предназначено для использования в качестве битового поля. Обычно такое перечисление именуется суффиксом Options или Flags или чем-то подобным. Аналогично, если каждый из перечислителей имеет заданное значение, которое является явно одним установленным битом, это перечисление, вероятно, предназначено для использования в качестве битового поля.

1 голос
/ 14 января 2011

Q1> Да. Вы используете enum, когда, казалось бы, хотите получить битовую маску.

Q2> Вы правы, это не имеет смысла. Использование перечисления подразумевает, что переменная all будет равна одному из элементов в параметрах, а не комбинации или нескольких элементов ..

0 голосов
/ 15 января 2011

Возможно, вам не удастся присвоить произвольное целочисленное значение переменной типа enum, но это плохой стиль.Как всегда, сначала читаем код, а потом компилятор.Ожидается, что переменная перечисления будет содержать только допустимые константы перечисления.

Я бы изменил последнюю строку на:

int all = ( Surf | Out); 
0 голосов
/ 15 января 2011

перечисления являются просто местозаполнителями для значений int, поэтому, когда вы поразрядно или их, вы получаете это: в двоичном формате (4-битное представление, так что мне проще): 0001 | 0010 = 0011 или 3. Перечисления могут принимать любые значения, даже полностью недействительные.

0 голосов
/ 15 января 2011

Помимо некоторых проблем с синтаксисом, ваш код работает. Но это вроде безвкусно. Перечисления являются целочисленными, но по стилю вы должны придерживаться значений, которые на самом деле находятся в перечислении.

Может быть, использовать другое int для побитовой коллекции. И будьте осторожны, чтобы назначить степени 2, я думаю. Если вы действительно хотите побитовый набор.

typedef enum Options
{
Surf     = 0x01,
Out      = 0x02
} Options;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...