我正在使用外部库(pcl),因此我需要一个不会更改现有函数原型的解决方案。
我正在使用的一个函数生成一个std::vector<int, Eigen::aligned_allocator<int>>
。我接下来要调用的函数需要一个const boost::shared_ptr<std::vector<int, std::allocator<int>>>
。我不想复制这些元素,因为它位于我的代码中已经很慢的关键部分。如果不是分配器不匹配,我可以通过简单地执行以下操作来绕过shared_ptr要求:
// code that generates std::vector<int, Eigen::aligned_allocator<int>> source
boost::shared_ptr<std::vector<int>> indices(new std::vector<int>);
indices->swap(source);
// use indices as intended
这不能使用 MSVC 编译器进行编译,因为它无法在这两种向量类型之间进行转换。到目前为止我想到的唯一不复制内容的解决方案是:
// code that generates std::vector<int, Eigen::aligned_allocator<int>> source
boost::shared_ptr<std::vector<int>> indices(new std::vector<int>);
indices->swap(reinterpret_cast<std::vector<int>&>(source));
// use indices as intended
indices->swap(reinterpret_cast<std::vector<int>&>(pcout.points));
请注意我如何需要将索引用作 const shared_ptr。我相信分配器不会在交换操作中发挥作用。整数也不需要任何填充来对齐,因为它们的大小已经是 32 位。 std::allocator 版本应该能够从对齐版本中读取,因为它只能在 std::allocator 本来可以使用的内存地址中进行分配。最后,我交换回来,因为如果对齐的分配器尝试删除未对齐的保留空间,它可能会崩溃。
我尝试了一下,它没有崩溃,但这还不足以让我相信它实际上是正确的。安全吗?如果不是,如果对编译器做出某些合理的假设,它是否有条件安全?是否有更安全且不会明显影响性能的替代方案?
请不要回复“分析您的代码”、“不值得”或类似的答案。即使它们在这里适用,理论上也存在复制不是可行的解决方案的情况,并且该线程应该解决这个问题。
类似问题 https://stackoverflow.com/questions/8190889/converting-between-vectors-with-different-allocators正在谈论以干净的方式复制数据,正如评论中所澄清的那样。
编辑:似乎尽管 Eigen::aligned_allocator 是为 16 位对齐而设计的,但没有向整数添加额外的填充。比较列表中第一个和最后一个元素的地址,给出元素数量和 sizeof(int) 所期望的大小。这意味着整数的存储方式应与 std::allocator 版本兼容。我希望今天晚些时候或未来几天我能有时间进行更完整的测试。