I am working with an external library (pcl) so I need a solution that does not change the existing function prototypes.
One function that I am using generates an std::vector<int, Eigen::aligned_allocator<int>>
. The function that I want to call next expects a const boost::shared_ptr<std::vector<int, std::allocator<int>>>
. I do not want to copy the elements because it is in an already slow critical part of my code. If not for the allocator mismatch, I would get around the shared_ptr requirement by simply doing:
// 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
This does not compile with the MSVC compiler because it cannot convert between these two vector types. The only solution I have thought of so far that does not copy the contents is:
// 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));
Note how I need to use indices as as a const shared_ptr. I believe that the allocator will not play a role in the swap operation. The ints should also not need any padding to be aligned as they are already of size 32-bit. The std::allocator version should be able to read from the aligned version because it can only allocate in memory addresses that the std::allocator could have used anyway. Finally, I swap back because the aligned allocator might crash if it tries to delete a non-aligned reserved space.
I tried it and it didn't crash but that is not enought to convince me that it is actually correct. Is it safe? If not, is it conditionally safe if certain reasonable assumptions are made concerning the compiler? Is there a safer alternative that does not noticeably impact performance?
Please do not reply with "profile your code", "not worth it" or similar answers. Even if they are applicable here, there is theoretically a scenario where copying is not a viable solution, and this thread should address that.
Similar question is talking about copying the data in a clean way as was clarified in the comments.
EDIT: it seems that despite Eigen::aligned_allocator being designed for 16-bit alignment, no extra padding is added to the ints. Comparing the address of the first and last element on the list gives the size one would expect from the number of elements and the sizeof(int). This means that the ints are stored in a way that should be compatible with the std::allocator version. I hope I'll have time later today or in the coming days to make a more complete test.