在 STL 中使用 void* 作为固定宽度记录
Working with void* as fixed width records in STL
我有一个连续的缓冲区,有 N 条记录,每条记录 W 字节宽。双N 和 W 在编译时是未知的。N*M 是 500mb 的订单。我想在标准的STL argorithms中使用它,例如sort()或nth_element()。我手头确实有一个比较器。有没有已经实施的方法可以做到这一点?
到目前为止,我想到了两种方法:
1)使用一个额外的向量,用索引0...N填充,对其进行排序(使用自定义比较器)而不是数据,使其类似于排序顺序的数据记录,然后根据该向量移动数据记录。缺点:额外的内存,额外的困难来修复数据记录顺序,这稍微不平凡。
2)创建一些自定义迭代器(知道W),它将返回一些类似于记录的临时"虚拟"类实例,并为该类重载swap(),以便它交换内存块。缺点:有点棘手,有点脆弱(需要遵循一些 STL 内部,例如知道将使用 swap()。
您的第二个选项(编写自定义迭代器)是一种可行的方法,并且效果很好。
您不需要依赖正在使用的swap
:您只需要重载在取消引用迭代器时返回的代理对象的赋值运算符。
(请注意,在 C++11 中,"交换"元素的算法和函数需要使用通过 ADL 找到的swap
函数。 不过,重载赋值运算符仍然更可取,特别是如果您只是移动字节数组。
我不知道我的头顶上的一般实现,但作为起点,您可以从我的一个库(靠近文件底部)查看stride_iterator
。 它包装一个字节数组并覆盖算术运算符,以一次将迭代器移动 N 个字节,其中 N 仅在运行时已知。
我会选择第二种方法,但通过提供自定义复制语义,而不是自定义swap
。使迭代器值类型成为保存void*
成员的类,并具有复制构造函数和复制该成员指向的记录的赋值运算符。这不依赖于任何实现细节。
我会投票支持选项 2),但您实际上不需要为存根类重载swap()
。您只需要:
- 创建由迭代器返回的"存根"类
- 实现默认的 ctor,它分配一个宽度为 W 的内存块
- 实现复制 ctor,它分配宽度为 W 的内存块,并复制内存的输入块
- 重载赋值运算符,以便将内存块从一个实例复制到另一个实例。
这样,swap()
将自动为您的班级工作。
- 如何检查是否定义了固定宽度的整数
- 当我尝试将范围值存储为 8 位的固定宽度整数时,它向我显示一些其他值 [ASCII]
- 是否有缺少固定宽度类型(intXX_t)的平台
- 何时应使用 C++ 固定宽度整数类型,它们如何影响性能?
- 使用固定宽度整数时,C 98 pedtical错误
- 为什么固定宽度类型会委托回基元
- 有没有理由不使用固定宽度类型
- 如何在 Windows 窗体应用程序 (C++) 中使用固定宽度整数
- iomanip /固定宽度持久性
- 为什么 std::setprecision(6) 在固定宽度模式式传输超过 6 位数字
- 在 STL 中使用 void* 作为固定宽度记录
- 删除浮点数上的科学记数法,而不强制固定宽度
- 为什么 stoi、stol 不是固定宽度的整数
- 在标准C++中是否存在固定宽度的布尔类型
- 如何使用cout设置固定宽度
- 固定宽度整数类型 std::uint8_t 和 std::int8_t 的实现,C++
- 固定宽度小部件在QSplitter
- GTK树视图固定宽度
- c++字符串格式化-固定宽度的浮点数,以及在偏移处有空格的字符串
- 固定宽度整数类型是否保证是标准内置类型的typedefs