简体   繁体   中英

Strange enum syntax in std library header

I was using a stringstream recently

stringstream ss (stringstream::in | stringstream::out);

and I decided to look at the declaration of in and out and I am somewhat confused with how they are declared. Would someone be able to clarify A. why they are written like this and B. how it works? I was expecting them to be written in standard enum syntax.

enum _Openmode
    {   // constants for file opening options
    _Openmask = 0xff};

static const _Openmode in = (_Openmode)0x01;
static const _Openmode out = (_Openmode)0x02;
static const _Openmode ate = (_Openmode)0x04;

Thanks

The standard actually requires that those constants are variables, not just enumerators ie they have addresses in memory instead of just being a label for a constant. It doesn't require that they are enums, they could be integers or bitsets instead. The spec requires:

// 27.5.3.1.4 openmode
typedef T3 openmode;
static constexpr openmode app = unspecified ;
static constexpr openmode ate = unspecified ;
static constexpr openmode binary = unspecified ;
static constexpr openmode in = unspecified ;
static constexpr openmode out = unspecified ;
static constexpr openmode trunc = unspecified ;

So to meet this requirement the type is declared (in your standard library as an enumeration), then several variables of that type are declared, with the necessary values.

An alternative implementation would be:

enum _Openmode
    {   // constants for file opening options
    _In = 0x01,
    _Out = 0x02,
    _Ate = 0x04,
    _Openmask = 0xff};

static const _Openmode in = _In;
static const _Openmode out = _Out;
static const _Openmode ate = _Ate;

Which would look more like you expect, but there's no advantage to doing it that way. If anything it's worse, because it adds additional unused names (_In, _Out, _Ate etc.) to the namespace, preventing those same names being used elsewhere in the implementation and (very slightly) slowing down name lookup.

The standard library is very often implemented in ways that seem unusual when compared to conventional application or library code. That's needed to meet the exact requirements of a standard library, which must be usable in every possible situation and also avoid causing problems (such as name collisions or linker errors) with user code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM