在我的几个项目中,我越来越需要处理内存中的连续位序列 - 高效(*)。到目前为止,我已经编写了一堆可内联的独立函数,以选择“位容器”类型(例如uint32_t
)为模板,用于获取和设置位,将“或”和“与”应用于它们的值,定位容器,以位为单位的长度转换为以字节为单位的大小或容器中的长度等......看起来这是编写类的时间。
我知道 C++ 标准库有一个专门化的std::vector<bool>
,这被许多人认为是一个设计缺陷——因为它的迭代器不暴露实际bool
的 s,而是代理对象。无论这对于专业化来说是一个好主意还是一个坏主意,这绝对是我正在考虑的东西 - 一个显式的位代理类,希望它“总是”被优化掉(用constexpr
,noexcept
和很好地润滑inline
)。因此,我正在考虑可能std::vector
从标准库实现之一改编代码。
另一方面,我的预期课程:
- 永远不会拥有数据/位-它将接收起始位容器地址(假设对齐)和位长度,并且不会分配或释放。
- 它将无法动态或以其他方式调整数据大小 - 即使在保留与 std::vector::resize() 相同的空间量时也不行;它的长度将在其生命周期/范围内固定。
- 它不应该对堆一无所知(并且在没有堆时工作)
从这个意义上说,它更像是位的跨度类。那么也许从跨度开始呢?我不知道,跨度仍然不标准;并且跨度中没有代理...
那么什么是我实现的良好基础(编辑:不是基类)?std::vector<bool>
? std::span
? 两个都?没有任何?或者 - 也许我正在重新发明轮子,这已经是一个已解决的问题?
笔记:
- 位序列长度在运行时是已知的,而不是编译时;否则,正如@SomeProgrammerDude 建议的那样,我可以使用
std::bitset
. - 我的班级不需要“成为”跨度或“成为”向量,所以我没有考虑专门研究其中任何一个。
(*) - 到目前为止,SIMD 效率不高,但可能会在以后出现。此外,这可以在我们不 SIMDize 而是假装通道是正确线程的 CUDA 代码中使用。