在给定这些选择的情况下,为什么库实现者会使用其中一个?
例如,llvm的libcxx似乎使用了这些实现选项中的两个(至少)两个的组合:
ctype_base :: mask使用整数类型实现:<__locale>
regex_constants :: Syntax_option_type是使用枚举重载运算符实现的:<regex>
gcc项目的libstdc使用全部三个:
ios_base :: fmtflags使用枚举重载运算符实现:<bits/ios_base.h>
regex_constants :: Syntax_option_type使用整数类型实现,
regex_constants :: match_flag_type使用std :: bitset实现
两者:<bits/regex_constants.h>
AFAIK,gdb无法“检测”这三个选项中的任何一个的位域,因此增强调试没有区别.
枚举解决方案和整数类型解决方案应始终使用相同的空间. std :: bitset似乎没有保证sizeof(std :: bitset< 32>)== std :: uint32_t所以我没有看到什么对std :: bitset特别有吸引力.
枚举解决方案似乎稍微不那么类型安全,因为掩码的组合不会生成枚举器.
严格来说,前面提到的是n3376而不是FDIS(因为我无法访问FDIS).
任何可用的启示在这方面将不胜感激.
解决方法
>整体类型是最简单的替代方案,但它们缺乏类型安全性.非常旧的遗留代码将倾向于使用这些,因为它们也是最古老的.
>枚举类型是安全但繁琐的,直到C 11,它们往往被固定为int的大小和范围.
> std :: bitset在该bitset< 5>中可能具有更多的类型安全性.和bitset< 6>是不同的类型,不允许添加,但在其他方面不太安全,就像一个整体类型.如果它们允许从std :: bitset< N>派生的类型,这将不是问题.
显然,枚举是理想的选择,但经验证明,类型安全是非常必要的.因此,他们向实施者提出了一个骨头,让他们可以采取更轻松的路线.简而言之,就是懒惰导致实施者选择int或bitset.
从bitset派生的类型是不允许的,这有点奇怪,但实际上这是一件小事.
子句提供的主要规范是在这些类型上定义的操作集(即,按位运算符).