C / C ++: извлечь подмножество одного перечисления, чтобы сформировать новое перечисление - PullRequest
4 голосов
/ 24 мая 2019

Скажем, у меня есть главное перечисление, перечисляющее весь персонал:

typedef enum all_personnel {
     // male
     TONY,
     MIKE,
     JIM,
     // female
     JESSICA,
     MARY,
} all_personnel_t;

Теперь я хочу определить два других перечисления для мужчины и женщины (потому что, например, некоторые функции принимают только аргумент перечисления мужчины или женщины), но я хочу использовать те же идентификаторы имени, что и в основном перечислении.Возможно ли это в C / C ++?Или есть другие способы?

Кажется, что следующее не работает (компилятор жалуется redeclaration of enumerator ‘TONY’ и т. Д .:

typedef enum male_personnel {
    TONY,
    MIKE,
    JIM,
} male_personnel_t;

Ответы [ 2 ]

6 голосов
/ 24 мая 2019

Как уже упоминалось здесь , вы можете сделать это в C ++, используя перечисленные области (C ++ 11) следующим образом

enum class all_personnel_t { TONY, MARY };
enum class male_personnel_t { TONY };

Или вы можете поместить перечисления в пространства имен следующим образом

namespace all
{
    enum all_personnel_t { TONY, MARY };
}
namespace male
{
    enum male_personnel_t { TONY };
}
5 голосов
/ 24 мая 2019

C

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

Согласно стандарту C11:

6.2.3 Пространства имен идентификаторов

  1. Таким образом, существуют разные пространства имен для различных категорий идентификаторов, а именно:
    ...
    - все остальные идентификаторы, вызываемые обычные идентификаторы (объявленные в обычных деклараторах или константы перечисления ).

C ++

Это возможно в C ++, если вы используете перечисления в области .

enum class all_personnel {
     // male
     TONY,
     MIKE,
     JIM,
     // female
     JESSICA,
     MARY,
} ;

enum class male_personnel {
    TONY,
    MIKE,
    JIM,
} ;

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

Таким образом, нижеследующее невозможно:

male_personnel mp2 = all_personnel::TONY; //will not work
all_personnel ap2 = male_personnel::MIKE; //will not work   

, и тоже:

male_personnel mp1 = male_personnel::MIKE; 
all_personnel ap1 = all_personnel::TONY; 
mp1 = ap1; //will not work

См. Демонстрация

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