Состав перечислений - PullRequest
2 голосов
/ 04 мая 2011

Есть ли способ сделать композицию из нескольких перечислений в C?Я хотел бы иметь общее перечисление, которое будет использоваться в других перечислениях.

Например, я хотел бы написать следующий код:

enum common_e {
   COMMON_LITERAL_0,
   COMMON_LITERAL_1
}

enum first_e {
   common_e, // <- Somehow I would like to have the two common_e's literals here
   FIRST_LITERAL_0,
}

enum another_e {
   common_e, // <- Somehow I would like to have the two common_e's literals here
   ANOTHER_LITERAL_0,
   ANOTHER_LITERAL_1
}

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

Есть ли решение для этого?

Ответы [ 5 ]

6 голосов
/ 04 мая 2011

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

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

enum common_e {
    COMMON_LITERAL_0,
    COMMON_LITERAL_1,
    COMMON_LITERAL_END__
};

enum first_e {
    FIRST_LITERAL_0 = COMMON_LITERAL_END__,
    FIRST_LITERAL_1
};
4 голосов
/ 04 мая 2011

Примерно так:

enum common_e {
   COMMON_LITERAL_0,
   COMMON_LITERAL_1,
   COMMON_MAX
}

enum first_e {
   FIRST_LITERAL_0 = COMMON_MAX,
}

enum another_e {
   ANOTHER_LITERAL_0 = COMMON_MAX,
   ANOTHER_LITERAL_1
}
2 голосов
/ 04 мая 2011

Ну, вы могли бы предположительно сделать что-то вроде этого:

#define COMMON_E(N) N##_COMMON_LITERAL_0, \
                    N##_COMMON_LITERAL_1

enum first_e {
   COMMON_E(FIRST), // <- Somehow I would like to have the two common_e's literals here
   FIRST_LITERAL_0,
};

enum another_e {
   COMMON_E(ANOTHER), // <- Somehow I would like to have the two common_e's literals here
   ANOTHER_LITERAL_0,
   ANOTHER_LITERAL_1
};

Хотя я не уверен, какая польза от этого будет ...

Проблема в том, что перечисления не являются пространствами имен, поэтому вам нужно указывать разные имена (отсюда и параметр макроса).

0 голосов
/ 04 мая 2011

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

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

enum every_e {
   // common values
   COMMON_LITERAL_0,
   COMMON_LITERAL_1,
   MAX_COMMON_LITERAL = COMMON_LITERAL_1,

   // First set of extra values
   FIRST_LITERAL_0 = MAX_COMMON_LITERAL+1,
   FIRST_LITERAL_1,
   FIRST_LITERAL_2,

   // Second set of extra values
   ANOTHER_LITERAL_0 = MAX_COMMON_LITERAL+1,
   ANOTHER_LITERAL_1
};

Если вы хотите использовать различные типы перечислений, вы можете использовать тот же трюк:

enum common_e {
   COMMON_LITERAL_0,
   COMMON_LITERAL_1,
   MAX_COMMON_LITERAL = COMMON_LITERAL_1
};

enum first_e {
   FIRST_LITERAL_0 = MAX_COMMON_LITERAL+1,
};

enum another_e {
   ANOTHER_LITERAL_0 = MAX_COMMON_LITERAL+1,
   ANOTHER_LITERAL_1
};
0 голосов
/ 04 мая 2011

Это невозможно в C. Вам просто нужно определить несколько перечислений.

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