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 anint
orunsigned 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 isint
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
thanint
unless the value of an enumerator cannot fit in anint
or
unsigned int
. If the enumerator-list is empty, the underlying type
is as if the enumeration had a single enumerator with value0
.
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 featureso 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. Enum
s are stored as int
s 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
, orulong
.
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
How to Make Objective-C Class Using Std:Vector Made Available to Swift Classes
How to Solve the Error Lnk2019: Unresolved External Symbol - Function
No Default Constructor Exists for Class X (Inheritance) C++
How to Convert a Char Array to a String
How to Append a Char to a Std::String
Conditional Operator Used in Cout Statement
How to Get the Position and Draw Rectangle Using Opencv
Why How to Access Private Variables in the Copy Constructor
Undefined Reference to Template Function
Can Class Template Constructors Have a Redundant Template Parameter List in C++20
Why Is the C++ Stl Is So Heavily Based on Templates? (And Not on *Interfaces*)
Vector::At VS. Vector::Operator[]
Boost.Asio-Based Http Client Library (Like Libcurl)
Does C++ Allow Default Return Types for Functions