Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C/C++: extract a subset of one enum to form a new enum

Tags:

c++

c

enums

Say I have a master enum listing all personnel:

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

Now I want to define other two enums for male and female (because, for example, some functions only takes males or females enum argument), but I want to use the same name identifiers as in the master enum. Is it possible in C/C++? Or there are other ways?

It seems that the following does not work (compiler complains redeclaration of enumerator ‘TONY’ etc:

typedef enum male_personnel {
    TONY,
    MIKE,
    JIM,
} male_personnel_t;
like image 281
bruin Avatar asked Dec 17 '22 17:12

bruin


2 Answers

As mentioned here, you can do this in C++ by using scoped enumerations (C++11) as follows

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

Or you can put the enums in namespaces as follows

namespace all
{
    enum all_personnel_t { TONY, MARY };
}
namespace male
{
    enum male_personnel_t { TONY };
}
like image 109
Bhavin Avatar answered Dec 31 '22 02:12

Bhavin


C

This is not possible in C because all enumeration constants from the different enumerations that are in scope are part of the same namespace called the ordinary identifiers namespace. So using the same name for the constants will result in a re-declaration error.

As per C11 standard:

6.2.3 Name spaces of identifiers

  1. Thus, there are separate name spaces for various categories of identifiers, as follows:
    ...
    — all other identifiers, called ordinary identifiers (declared in ordinary declarators or as enumeration constants).

C++

This is possible in C++, if you use scoped enumerations.

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

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

However, note that there are no implicit conversions from the values of a scoped enumerator to integral types or from one scoped enumerator to another scoped enumerator. This is because each enumerator becomes a named constant of the enumeration's type.

So the below is not possible:

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

and neither is this:

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

See Demo

like image 32
P.W Avatar answered Dec 31 '22 01:12

P.W