Вопрос о перечислениях в C ++ - PullRequest
4 голосов
/ 04 сентября 2011

Я пытался использовать перечисление в цикле for следующим образом:

enum foo
{
    foo_0, 
    foo_1,
    foo_2,
    foo_3,
    ...
    foo_n,
    foo_count
};

for(foo f = foo_0; f < foo_count; ++f) 

и у меня произошла ошибка компиляции. Я понимаю, что это недопустимо, потому что ++ f может быть недопустимым перечислением foo - не в этом случае, а в общем случае, поэтому я переключил цикл for на это:

for(foo f = foo_0; f < foo_count; f = foo(f+1)) 

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

foo f = foo(k); //k is not a valid foo value

Это неопределенное поведение?

РЕДАКТИРОВАТЬ: k является int и не имеет соответствующего значения в foo

EDIT2:

enum foo
{
    foo_0, 
    foo_1,
    foo_2,
    foo_3
};

foo f = foo(100); //what value will have f after this according to the standard

Спасибо за помощь!

Ответы [ 3 ]

7 голосов
/ 04 сентября 2011

У меня была ошибка компиляции.Я понимаю, что это недопустимо, поскольку ++ f может быть недопустимым перечислением foo.

Нет.Это неверное толкование ошибки.Он не компилируется, потому что operator++ не определено для foo типа.

Если вы определите operator++ как:

foo & operator++(foo & f) 
{  
   return f = foo(f+1); 
}

Тогда ++f скомпилирует и будет работать: http://ideone.com/1GG09

А что касается foo(f+1) (или foo(k)), тогда все в порядке.Внутренне foo является целочисленным типом.И это значение может быть любым, что может быть представлено базовым целочисленным типом.

§7.2 / 6 гласит:

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


РЕДАКТИРОВАТЬ:

 foo f = foo(100); //what value will have f after this according to the standard

Я думаю, что поведение не указано здесь, как сказано в Стандарте в §7.2 / 9,

Выражение арифметического или перечислимого типа может быть явно преобразовано в перечислимый тип.Значение не изменяется , если оно находится в диапазоне значений перечисления типа перечисления; в противном случае результирующее значение перечисления не указано.

Диапазон перечисления см. В предыдущей цитате.

4 голосов
/ 04 сентября 2011

Это определенное поведение. Значение, которое заканчивается на f, не указывается, если k находится вне диапазона значений foo и совпадает с k, если оно находится в диапазоне значений foo.

Диапазон foo равен 0 .. 2^(ld(n+2)+1) - 1. То есть значения битового поля, которое может хранить все значения ваших констант перечисления (перечислителей).

0 голосов
/ 04 сентября 2011

В этом случае f будет иметь значение k, но это не соответствует метке в enum. Думайте о enum как unsigned int как о типе данных (если не указано иное), а идентификаторы внутри enum как о константах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...