標準では、実際にはこれらの定数が単なる列挙子ではなく変数であることを要求しています。つまり、定数のラベルではなく、メモリ内にアドレスを持っている必要があります。列挙型である必要はありません。代わりに、整数またはビットセットにすることができます。仕様には次が必要です。
// 27.5.3.1.4オープンモード
typedef T3 オープンモード;
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 ;
したがって、この要件を満たすために、型が宣言され (標準ライブラリで列挙型として)、その型のいくつかの変数が必要な値と共に宣言されます。
別の実装は次のようになります。
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;
これはあなたが期待するように見えますが、そのようにする利点はありません。さらに悪いことに、未使用の名前 (_In、_Out、_Ate など) が名前空間に追加され、同じ名前が実装の他の場所で使用されなくなり、名前検索が (非常にわずかに) 遅くなります。
標準ライブラリは、従来のアプリケーションやライブラリ コードと比較すると、通常とは異なる方法で実装されることがよくあります。これは、考えられるあらゆる状況で使用でき、ユーザー コードで問題 (名前の競合やリンカー エラーなど) が発生しないようにする必要がある、標準ライブラリの正確な要件を満たすために必要です。