Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Size of array has non-integral type when using c++11 enum class

Tags:

enums

c++11

I used this code:

enum E {
    E1, E2, E3, MaxNum
};

const char * ENames[ MaxNum ] = {
    "E1", "E2", "E3"
};

and had no problem. Now I want to use "modern" enum class. The code now looks like this:

enum class E {
    E1, E2, E3, MaxNum
};

const char * ENames[ E::MaxNum ] = {
    "E1", "E2", "E3"
};

and got an error

error: size of array ‘ENames’ has non-integral type ‘E’

error: too many initializers for ‘const char* [1]’

Q: why enum class does become non-integral in c++11, while usual enum is integral ?

What is a decision of a problem ? How can I declare an array with size, that is one of enumeration in enum class ?

Here - http://ideone.com/SNHTYe - is a simple example.

Thank you.

like image 780
borisbn Avatar asked Jun 28 '13 07:06

borisbn


2 Answers

Q: why enum class does become non-integral in c++11, while usual enum is integral ?

Because it's not a "usual enum", it's more strongly-typed

How can I declare an array with size, that is one of enumeration in enum class ?

Why do you want to anyway? You could use a static_cast but the solution to your problem is "don't do that".

If you want an enum of fixed underlying type then do that, don't use a scoped enum:

enum E : uint16_t {
    E1, E2, E3, MaxNum
};

const char * ENames[ MaxNum ] = {
    "E1", "E2", "E3"
};
like image 170
Jonathan Wakely Avatar answered Nov 04 '22 11:11

Jonathan Wakely


C++11 5.19/3 "Constant expressions"

An integral constant expression is a literal constant expression of integral or unscoped enumeration type.

Scoped enumerations are not integral constant expressions. And an array dimension (if specified) must be "an integral constant expression and its value shall be greater than zero" (8.3.4/1 "Arrays").

I suspect that the rationale for this is that scoped enums do not implicitly convert to int.

To work around the problem, you could static cast the scoped enum to an int as suggested by user2523017, or use the pre-C++11 methods of scoping enum names:

namespace E {
enum {
      E1, E2, E3, MaxNum
    };
}

or:

struct E {
enum {
      E1, E2, E3, MaxNum
    };
};
like image 26
Michael Burr Avatar answered Nov 04 '22 10:11

Michael Burr