对于std::bitset
(std禁止)的实现,我使用了uint_fast32_t
,因为它在64位CPU上更快。一个评论是为小集合保存空间,例如。例如,bitset不应该使用8个字节<6>。如果考虑到结构中的对齐,则浪费会更多。
用C++11就可以了。我想优雅地选择:
- 大小〈= 8:uint8_t
- 大小〈= 16:uint16_t
- 大小〈= 32:uint32_t
- 大小〉32:uint_fast32_t
作为我的类中的存储类型:
template<size_t Size>
struct BitSet {
typedef <expression> StorageType;
// an array of that storage type...
};
我只能想到一些相当笨拙的辅助模板,但也许在C++11中有一些更优雅的东西。
编辑:澄清:uint_fast8_t
对于原始类来说是合适的,编译器可以选择任何快的。想象大小==1000000。但在某些机器上它可能是64位的,当在某些用例中大小很重要时,e。例如,大小==4,这意味着将浪费7个字节。
6条答案
按热度按时间mwngjboj1#
考虑到可能的类型的小选择,我只需要硬编码条件:
或者,使用类似于@Caleth的答案的技巧:
sr4lhrrt2#
带着帮手
然后我们可以对
constexpr
个布尔值求和jobtbby33#
您可以使用递归模板类,并将非类型模板参数用于位限制,将成员类型别名用于相应的整数类型。
你不需要自己编写这样的模板,Boost已经涵盖了:
boost::uint_t<N>::least
(或者boost::uint_t<N>::fast
,如果你不是在寻找最小但最快的)。P.S.如果你打算自己实现这个模板,并且你想要最小整数类型(根据标题中的问题),那么你应该使用
std::uint_leastN_t
而不是uint_fastN_t
或uintN_t
。前者不一定是最小的类型,后者也不保证在所有系统上都存在。此外,
uint_fast32_t
不能保证能够表示超过32位的位,因此对于Size > 32
来说,这是一个相当糟糕的选择。我会推荐uint_least64_t
代替。k3fezbri4#
一个冗长的解决方案,少魔术。参考:https://gcc.godbolt.org/z/P2AGZ8
hc2pp10m5#
如果你的编译器支持的话,你也可以使用
constexpr if
--这可能是最容易阅读的一个。基于以下代码的示例:ivqmmu1c6#
简单的解决方案:
这是简单地使用
bit_width
,即。最小位数,可以适应索引所有类型的std::tuple
所需的最大值。C++20有一个
std::bit_width
,即constexpr
,但如果需要,很容易编写自己的版本。