A quote from C++11 standard (17.5.2.1.2 Enumerated types):
1 Several types defined in Clause 27 are enumerated types. Each enumerated type may be implemented as an enumeration or as a synonym for an enumeration (Such as an integer type, with constant integer values (3.9.1)).
2 The enumerated type enumerated can be written:
enum enumerated { V0 , V1 , V2 , V3 , ..... };
static const enumerated C0 (V0 );
static const enumerated C1 (V1 );
static const enumerated C2 (V2 );
static const enumerated C3 (V3 );
.....
3 Here, the names C0, C1, etc. represent enumerated elements for this particular enumerated type. All such elements have distinct values.
One of such "enumerated types" is "seekdir" from class ios_base (27.5.3 Class ios_base):
// 27.5.3.1.5 seekdir
typedef T4 seekdir;
static constexpr fmtflags beg = unspecified ;
static constexpr fmtflags cur = unspecified ;
static constexpr fmtflags end = unspecified ;
and
27.5.3.1.5 Type ios_base::seekdir [ios::seekdir]
typedef T4 seekdir;
1 The type seekdir is an enumerated type (17.5.2.1.2) that contains the elements indicated in Table 126.
So, the ONLY reason those static const and constexpr members are required is because "enumerated types" are allowed to be implemented as integer type (i.e. when enumerated is int we need to define constants in place of enumerators), right?
Question 1. If library vendor decides to implement seekdir as enum does he still have to define static constants for enumeration values?
Question 2. WHY "enumerated types" are allowed to be implemented as integer types in the first place? I.e. when enum implementation (and in C++11 enums can have any underlying integer type) without those static constant members can be worse than integer type implementation?
When the standard was written, strongly-typed enums weren't available and the problem with plain enum
is, that their internal type is unspecified and may change depending on compiler switches.
For seekdir
, it could be int
or byte
(as an example), both would be valid representations. GCC has an command line option for that (--short-enums
or -fshort-enums
), by default it would use int
for all enum
s as the smallest type, but with the option it would use the smallest type that could contain all values.
That means that if a real enum
is used in a function signature, the symbol may change and you'd need to recompile everything. This is why the Standard allows other options, why it's important for the Standard Library implementation to have control over the type and this is why it is allowed to resort to specific integer types.
The original reason for requiring objects for the values of enumerated types was so that you could take their address. That always struck me as silly, but there was quite a bit of overdesign in the early stages of standardization.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With