Два перечисления имеют некоторые общие элементы, почему это приводит к ошибке? - PullRequest
29 голосов
/ 29 января 2010

В моем коде есть два перечисления:

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' .

Почему так сказано? И как мне это обойти?

Ответы [ 8 ]

35 голосов
/ 29 января 2010

Имена перечислений находятся в глобальной области видимости, они должны быть уникальными. Помните, что вам не нужно квалифицировать символы перечисления с именем перечисления, вы просто делаете:

Month xmas = December;

не

Month xmas = Month.December;  /* This is not C. */

По этой причине вы часто видите людей, которые ставят префикс имени символа с именем enum:

enum Month { Month_January, Month_February, /* and so on */ };
29 голосов
/ 29 января 2010

Я предлагаю вам объединить два:

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, ....
13 голосов
/ 29 января 2010

В C ++, чтобы избежать конфликта имен, вы можете заключить перечисления в структуры:

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}; };
7 голосов
/ 29 января 2010

То, что раскрутил, сказал. Но я также хотел бы сказать, что ваш пример выглядит как довольно необычное использование перечислений. Я не вижу смысла в том, чтобы ShortMonth и LongMonth ссылались на одно и то же - это имело бы смысл для строк, но не для перечислений. Почему бы просто не иметь тип enum для одного месяца?

3 голосов
/ 29 января 2010

Мое предложение здесь - иметь только одно перечисление, так как они одного типа.Если вы хотите, чтобы короткие псевдонимы набирали меньше в вашем коде (даже если бы я не советовал вам это делать), вы можете сделать:у вас должно быть два разных строковых массива, которые индексируются перечислением.

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]);
2 голосов
/ 11 июля 2017

В C ++ 11 вы можете использовать перечисления в области , чтобы исправить это. Это удалит имена из глобальной области видимости и поместит их в имя перечисления.

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;
}

Живой пример

1 голос
/ 29 января 2010

В C перечисления используются без префикса типа, поэтому вы пишете:

month[0] = January;  
month[4] = May;

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

0 голосов
/ 28 марта 2017
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;

Слияние их в одно

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