如何将带有自定义分配器的std :: vector传递给期望使用std :: allocator的函数?

pat*_*gan 5 c++ boost vector allocator

我正在使用外部库(pcl),所以我需要一个不会改变现有函数原型的解决方案.

我正在使用的一个功能生成一个std::vector<int, Eigen::aligned_allocator<int>>.我想要接下来调用的函数需要a 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
Run Code Online (Sandbox Code Playgroud)

这不能使用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));
Run Code Online (Sandbox Code Playgroud)

注意我需要如何使用索引作为const shared_ptr.我相信分配器不会在交换操作中发挥作用.int也应该不需要对齐任何填充,因为它们已经是32位大小.std :: allocator版本应该能够从对齐版本中读取,因为它只能分配std :: allocator可能已经使用过的内存地址.最后,我换回,因为如果尝试删除未对齐的保留空间,则对齐的分配器可能会崩溃.

我尝试了它并没有崩溃,但这并不是说服我确实它是正确的.安全吗?如果没有,如果对编译器做出某些合理的假设,它是否有条件安全?有没有更明显影响性能的更安全的替代方案?

请不要回复"描述您的代码","不值得"或类似的答案.即使它们适用于此,理论上也存在复制不是可行解决方案的情况,并且该线程应该解决这个问题.

类似的问题是谈论以清晰的方式复制数据,如评论中所阐明的那样.

编辑:似乎尽管Eigen :: aligned_allocator设计用于16位对齐,但没有额外的填充添加到整数.比较列表中第一个和最后一个元素的地址给出了元素数量和sizeof(int)的大小.这意味着int以一种应该与std :: allocator版本兼容的方式存储.我希望我今天晚些时候或在未来几天有时间做一个更完整的测试.

Cur*_*ous 4

如果您有能力将函数原型更改为另一种向量类型,那么namespace pmr标准库中就有一个全新的命名空间 ( ),它对分配器使用类型擦除,以确保使用不同分配器的容器之间的兼容性。

有关更多信息,请参阅polymorphic_allocator:何时以及为何应使用它?

通过这个改变,你可以简单地做

void foo(std::pmr::vector<int>& vec); 
Run Code Online (Sandbox Code Playgroud)

并使用您想要的任何分配器(只要它也是 a std::pmr::vector)传入向量类型。

如果您无法更改函数期望的向量类型,我认为您不能比一一复制/移动元素做得更好。

reinterpret_cast将两个不同的向量实例转换为不同的类型,然后对它们使用方法是非常危险的。