What Is the Underlying Type of a C++ Enum

What is the underlying type of a c++ enum?

From N4659 C++ 7.2/5:

For an enumeration whose underlying type is not fixed, the underlying type is an integral type that can represent all the enumerator values defined in the enumeration. If no integral type can represent all the enumerator values, the enumeration is ill-formed. It is implementation-defined which integral type is used as the underlying type except that the underlying type shall not be larger than int unless the value of an enumerator cannot fit in an int or unsigned int. If the enumerator-list is empty, the underlying type is as if the enumeration had a single enumerator with value 0.

Underlying type of a C++ enum in C++0x

I haven't read any C++0x stuff so I couldn't comment on that.

As for serializing, you don't need the switch when reading the enum back in - just cast it to the enum type.

However, I don't cast when writing to the stream. This is because I often like to write an operator<< for the enum so I can catch bad values being written, or I can then decide to write out a string instead.

enum color { red, green, blue };
color c = red;

// to serialize
archive << c; // Removed cast

// to deserialize
int i;
archive >> i;
c = (color)i; // Removed switch

Determine underlying integral type of an Enum in C#

You can use Enum.GetUnderlyingType:

Console.WriteLine("Type: {0} - {1}.", type.Name, Enum.GetUnderlyingType(type).Name);

why is the default type of enum class different than the underlying type of enum?

As far as N4140 is concerned, MSVC is correct:

§7.2/5 Each enumeration defines a type that is different from all
other types. Each enumeration also has an underlying type. The
underlying type can be explicitly specified using an enum-base. For
a scoped enumeration type, the underlying type is int if it is not
explicitly specified. [...]

For rationale, you can read the proposal entitled Strongly Typed Enums (Revision 3) N2347. Namely, section 2.2.2 Predictable/specifiable type (notably signedness) explains that the underlying type of enum is implementation-defined. For example, N4140 again:

§7.2/7 For an enumeration whose underlying type is not fixed, the
underlying type is an integral type that can represent all the
enumerator values defined in the enumeration. If no integral type can
represent all the enumerator values, the enumeration is ill-formed. It
is implementation-defined which integral type is used as the
underlying type except that the underlying type shall not be larger
than int unless the value of an enumerator cannot fit in an int or
unsigned int. If the enumerator-list is empty, the underlying type
is as if the enumeration had a single enumerator with value 0.

And N2347's proposed solutions:

This proposal is in two parts, following the EWG direction to date:

• provide a distinct new enum type having all the features that are
considered desirable:

o enumerators are in the scope of their enum


o enumerators and enums do not implicitly convert to int


o enums have a defined underlying type


• provide pure backward-compatible extensions for plain enums with a
subset of those features

o the ability to specify the underlying type


o the ability to qualify an enumerator with the name of the enum


The proposed syntax and wording for the distinct new enum type is
based on the C++/CLI [C++/CLI] syntax for this feature. The proposed
syntax for extensions to existing enums is designed for similarity.

So they went with the solution to give scoped enums a defined underlying type.

Are enum types stored as ints in C#?

From the MSDN

The default underlying type of enumeration elements is int.

By default, the first enumerator has the value 0, and the value of each successive enumerator is increased by 1.

So your assumptions are correct. Enums are stored as ints and your example will be represented as 0, 1, 2. However, you shouldn't rely on this and always refer to them by their assigned name just in case someone overrides the default.

What's the use-case for specifying the underlying type in enums?

Not much point, really, except that if the default underlying type (int) is not enough for you, ie. you want to use higher integer values than that then you can make it long. This can be useful when you have a [Flags] enum with more than 32 values.

You can make it byte or short just to restrict the range of values, but it will actually still take 4 bytes (ie. same as int).

C# BaseType of enum

You want an Underlying type, not Base type:

var underlyingType = Enum.GetUnderlyingType(typeof(ConsoleColor))

Also note that any specific enum (like your Color) is a value type and base type of System.Enum is System.ValueType (despite the fact that System.Enum is a reference type). That's why your typeof(Color).BaseType.BaseType equals System.ValueType

Why should I make the underlying type of an Enum Int32 instead of byte?

Have a look on MSDN for the reason.

Here is an excerpt:

An enumeration is a value type that defines a set of related named
constants. By default, the System.Int32 data type is used to store the
constant value. Even though you can change this underlying type, it is
not necessary or recommended for most scenarios. Note that no
significant performance gain is achieved by using a data type that is
smaller than Int32. If you cannot use the default data type, you
should use one of the Common Language System (CLS)-compliant integral
types, Byte, Int16, Int32, or Int64 to make sure that all values of
the enumeration can be represented in CLS-compliant programming
languages.

Define enum representation type in C#

Yes, you can change the type of an enum but not to char. For your byte can work well as it's 1 byte type. Check enum (C# reference) on MSDN (emphasis mine):

Every enumeration type has an underlying type, which can be any integral type except char. The default underlying type of enumeration elements is int. To declare an enum of another integral type, such as byte, use a colon after the identifier followed by the type, as shown in the following example.

enum Days : byte {Sat, Sun, Mon, Tue, Wed, Thu, Fri};

The approved types for an enum are byte, sbyte, short, ushort, int, uint, long, or ulong.

how to specify an underlying type for enum in F#

You can't use bit shifting, but isn't this even better?

type MyKinds = 
| None = 0b0000us
| Flag1 = 0b0001us
| Flag2 = 0b0010us

Also, if these are to be used as bit flags, you might want to add the [<Flag>] attribute, so that printing the value will show any combination of flags.



Related Topics



Leave a reply



Submit