einpoklum einpoklum - 24 days ago 7
C++ Question

Why can't I have an enum as the underlying type of another enum?

Why isn't this valid C++?:

enum foo : unsigned { first_foo, second_foo };
enum bar : foo { best_foo = first_foo };


GCC 5.4.0 says:

/tmp/a.cpp:3:16: error: underlying type ‘foo’ of ‘bar’ must be an integral type
enum bar : foo { best_foo = first_foo };


I can understand why I would get this error if
foo
were a
float
, or some struct, or what-not. But this seems perfectly legit to me in terms of semantics, type safety etc. What am I missing?

Answer

For me it is a logical error to say a enum can be based on an another enum. If you think that the base is the storage type where the values defined in the enum are stored in, I can not get it as a logic expression to say the storage type is an enum. Because the enum is not only the storage type, it also contains a set of valid values.

If we can write something like:

enum A: int { ONE, TWO };

what should mean:

enum B: A{};

Because A defines not only the underlaying type ( I call this the storage type ) but also a set of valid values, should B only a subset of the enum A which means that you can define only values already defined in A?

Is it now valid to say we habe the values ONE,TWO already defined also in B? And is it now possible to add more values like:

    enum B: A{THREE};

and all valid values are now ONE,TWO,THREE ?

or is the meaning we get only the subset:

    enum B: A{ONE};

which means B can only use values already defined in A. Simply that makes it difficult to me to make a enum a base of another enum.

If you open that door, you also can also come to the idea that you want to use the underlaying storage type from other kinds of types like bitfields.

struct A { unsigned int a : 3; unsigned int B: 2; };

should then

enum B: A { ONE, TWO };

also be valid? I believe not! ;)

From the logical point ( my point of view ) the underlaying type of the enum is its storage type. And it makes no sense to make an enum as an underlaying storage type for another enum at all.