У двух перечислений есть некоторые общие элементы, почему это вызывает ошибку?
У меня есть два перечисления в моем коде:
enum Month {January, February, March, April, May, June, July,
August, September, October, November, December};
enum ShortMonth {Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec};
May
является общим элементом обоих перечислений, поэтому компилятор говорит:
Переобучение перечислителя 'May
'.
Почему он так говорит? И как я могу обойти это?
Ответы
Ответ 1
Имена имен перечислены в глобальной области, они должны быть уникальными. Помните, что вам не нужно квалифицировать символы перечисления с именем перечисления, вы просто:
Month xmas = December;
не
Month xmas = Month.December; /* This is not C. */
По этой причине вы часто видите людей, которые префикс имен символов имеют имя перечисления:
enum Month { Month_January, Month_February, /* and so on */ };
Ответ 2
Я предлагаю вам объединить два:
enum Month {
Jan, January=Jan, Feb, February=Feb, Mar, March=Mar,
Apr, April=Apr, May, Jun, June=Jun,
Jul, July=Jul, Aug, August=Aug, Sep, September=Sep,
Oct, October=Oct, Nov, November=Nov, Dec, December=Dec};
который будет иметь точно такой же эффект и более удобен.
Если вы хотите, чтобы в январе значение 1 вместо 0, добавьте это:
enum Month {
Jan=1, January=Jan, Feb, February=Feb, ....
Ответ 3
В С++, чтобы избежать столкновения имен, вы могли бы перевести ваши перечисления в структуры:
struct Month { enum {January, February, March, April, May, June, July,
August, September, October, November, December}; };
struct ShortMonth { enum {Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec}; };
Ответ 4
Расскажите, пожалуйста. Но я также хотел бы сказать, что ваш пример кажется довольно необычным использованием перечислений. Я не вижу значения наличия ShortMonth и LongMonth, ссылающихся на одно и то же - это имеет смысл для строк, но не для перечислений. Почему бы не просто создать один месяц для перечисления?
Ответ 5
Мое предложение здесь состоит в том, чтобы иметь только одно перечисление, поскольку они одного типа. Если вы хотите, чтобы короткие псевдонимы вводили меньше кода (даже если бы я не советовал вам это делать), вы можете сделать:
enum Month {
January, Jan = January,
February, Feb = February,
March, Mar = March,
April, Apr = April
May,
June, Jun = June,
July, Jul = July,
...};
И чтобы иметь разные имена представлений (короткие и длинные), у вас должно быть два различных строковых массива, индексированных перечислением.
char[MAX_MONTH_NAME_LENGTH][12] month_long_names = {
"January", "February", ...
}
char[3][12] short_long_names = {
"Jan", "Feb", ...
}
printf("month %d long name is %s, and short name is %s\n", May, long_month_names[May], short_month_names[May]);
Ответ 6
В C перечислениях используются без префикса любого типа, поэтому вы пишете:
month[0] = January;
month[4] = May;
Месяц перечисления и ShortMonth имеют одинаковую область действия, поэтому компилятор не может знать, какой май использовать. Очевидным решением было бы префикс перечислений, но я не уверен, что использование этих перечислений в этом случае оправданно.
Ответ 7
В С++ 11 вы можете использовать scoped перечисления, чтобы исправить это. Это позволит удалить имена из глобальной области и объединить их в имя перечисления.
enum class Identity
{
UNKNOWN = 1,
CHECKED = 2,
UNCHECKED =3
};
enum class Status
{
UNKNOWN = 0,
PENDING = 1,
APPROVED = 2,
UNAPPROVED =3
};
int main ()
{
Identity::UNKNOWN;
Status::UNKNOW;
}
Живой пример
Ответ 8
typedef enum {Jan, January, Feb, February, Mar, March, Apr, April, May, Jun, June, Jul, July,
Aug, August, Sep, September, Oct, October, Nov, November, Dec, December} Month,ShortMonth;
Объединить их в один