7

该标准允许人们在整数类型、anenum和 a之间进行选择std::bitset

考虑到这些选择,为什么库实现者会使用其中一个?

例如,llvm 的 libcxx 似乎使用了(至少)以下两个实现选项的组合:

ctype_base::mask使用整数类型实现: <__locale>

regex_constants::syntax_option_type使用enum+ 重载运算符实现: <regex>

gcc 项目的 libstdc++ 使用所有三个

ios_base::fmtflags使用枚举 + 重载运算符实现:<bits/ios_base.h>

regex_constants::syntax_option_type使用整数类型 regex_constants::match_flag_type实现,使用std::bitset
Both 实现:<bits/regex_constants.h>

AFAIK,gdb 无法“检测”这三个选项中任何一个的位域,因此增强调试不会有区别。

enum解决方案和整数类型解决方案应始终使用相同的空间。std::bitset似乎没有做出保证,sizeof(std::bitset<32>) == std::uint32_t所以我看不出有什么特别吸引人的地方std::bitset

enum解决方案似乎不太安全,因为掩码的组合不会生成枚举器。

严格来说,上述内容是关于n3376而不是 FDIS(因为我无权访问 FDIS)。

在这方面的任何可用启示将不胜感激。

4

3 回答 3

2

My preference is to use an enum, but there are sometimes valid reasons to use an integer. Usually ctype_base::mask interacts with the native OS headers, with a mapping from ctype_base::mask to the <ctype.h> implementation-defined constants such as _CTYPE_L and _CTYPE_U used for isupper and islower etc. Using an integer might make it easier to use ctype_base::mask directly with native OS APIs.

I don't know why libstdc++'s <regex> uses a std::bitset. When that code was committed I made a mental note to replace the integer types with an enumeration at some point, but <regex> is not a priority for me to work on.

于 2012-05-04T22:38:22.180 回答
2

真正令人惊讶的是,该标准将其限制为仅三种选择。为什么不应该接受类类型?总之……</p>

  • 整型是最简单的替代方案,但它们缺乏类型安全性。非常旧的遗留代码将倾向于使用这些,因为它们也是最古老的。
  • 枚举类型安全但繁琐,在 C++11 之前,它们倾向于固定为int.
  • std::bitset可能在这方面具有更多的类型安全性bitset<5>并且bitset<6>是不同的类型,并且不允许添加,但在其他方面就像整数类型一样不安全。如果他们允许.std::bitset<N>

显然enums 是理想的替代方案,但经验证明类型安全确实没有必要。因此,他们向实施者扔了一块骨头,让他们采取更简单的路线。那么,简短的回答是,懒惰导致实施者选择intbitset

bitset不允许派生的类型有点奇怪,但实际上这是一件小事。

该子句提供的主要规范是在这些类型上定义的一组操作(即按位运算符)。

于 2012-03-27T04:16:32.323 回答
0

为什么该标准允许以不同的方式实现该库?答案是:为什么不呢?

如您所见,这三个选项显然都在某些实现中使用。如果可以避免的话,该标准不想使现有的实现不符合标准。

使用 bitset 的一个原因可能是它的大小比枚举或整数更适合。并非所有系统都具有std::uint32_t. 也许 abitset<24>会在那里工作得更好?

于 2012-03-25T06:46:03.553 回答