【发布时间】:2018-11-23 14:28:53
【问题描述】:
在我的几个项目中,我越来越需要处理内存中的连续位序列 - 高效 (*)。到目前为止,我已经编写了一堆可内联的独立函数,以选择“位容器”类型(例如uint32_t)为模板,用于获取和设置位,将“或”和“和”应用于它们的值,定位容器,将位长度转换为字节大小或容器长度等......看起来是编写类的时间。
我知道 C++ 标准库有一个专门化的 std::vector<bool>,许多人认为这是一个设计缺陷——因为它的迭代器没有暴露实际的 bools,而是代理对象。无论这对于专业化来说是个好主意还是坏主意,这绝对是我正在考虑的事情 - 一个明确的位代理类,希望它“总是”被优化掉(用constexpr,@987654326 进行很好的润滑@ 和 inline)。因此,我正在考虑可能从标准库实现之一改编std::vector 代码。
另一方面,我的预期课程:
- 永远不会拥有数据/位 - 它将接收起始位容器地址(假设对齐)和位长度,并且不会分配或释放。
- 它将无法动态或以其他方式调整数据大小 - 即使在保留与 std::vector::resize() 相同的空间量时也不行;它的长度将在其生命周期/范围内固定。
- 它应该对堆一无所知(并且在没有堆时工作)
从这个意义上说,它更像是位的跨度类。那么也许从跨度开始呢?我不知道,跨度仍然不标准;并且跨度中没有代理...
那么,什么是我实现的良好基础(edit: 不是基类)? std::vector<bool>? std::span?两个都?没有?或者 - 也许我正在重新发明轮子,而这已经是一个已解决的问题?
注意事项:
- 位序列长度在运行时已知,而不是编译时;否则,正如@SomeProgrammerDude 建议的那样,我可以使用
std::bitset。 - 我的班级不需要“be-a”跨度或“be-a”向量,所以我没有考虑专门研究其中的任何一个。
(*) - 到目前为止,SIMD 效率不高,但可能会在以后出现。此外,这可以用于我们不 SIMDize 而是假装通道是正确线程的 CUDA 代码中。
【问题讨论】:
-
std::bitset?而且我真的不建议专门化std::vector,从那时起你基本上只是要重新实现std::vector<bool>。相反,您可能希望创建自己的课程,以更好地满足您的要求,并且可以足够开放以纳入您的未来计划。 -
@Someprogrammerdude:请参阅我的编辑中的“注释”。
-
根据我的想象,我将从
std::span实现开始——可以在网上找到——并从vector<bool>借用位代理。 -
为什么不在你的类中存储原始 ptr 和长度,然后提供一些函数来检查位?因为它是非欠的,所以不需要副本。
-
@BeeOnRope:因为我想使用代理,所以代码的结构会有点不同。不过谢谢。
标签: c++ stdvector class-design c++20 std-span