我最近在使用字符串流
stringstream ss (stringstream::in | stringstream::out);
我决定查看在和 out 中的声明,我对它们的声明方式感到有些困惑。有人能够澄清A.为什么他们这样写,B。它是如何工作的?我希望它们能用标准的枚举语法编写。
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;
由于
答案 0 :(得分:7)
标准实际上要求那些常量是变量,而不仅仅是枚举器,即它们在内存中有地址而不仅仅是常量的标签。它不要求它们是枚举,它们可以是整数或位组。规范要求:
// 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 ;
为了满足这个要求,声明了类型(在标准库中作为枚举),然后声明了该类型的几个变量,并带有必要的值。
另一种实现方式是:
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等),从而防止在实现的其他地方使用这些相同的名称,并且(非常轻微地)减慢名称查找速度。
与传统应用程序或库代码相比,标准库通常以看似不寻常的方式实现。这需要满足标准库的确切要求,标准库必须在每种可能的情况下都可用,并避免与用户代码一起引起问题(例如名称冲突或链接器错误)。