What will be an efficient way of converting a std::vector<Boost::any> to a std::vector<float>

218 Views Asked by At

I can use a loop to copy elements from boost::any vector to std::vector of floats.

It is inefficient in the sense that there are 50000 values to copy, vector can grow beyond 50K and I have to save the to the disk in different folders. So it is a bottleneck.

So far the following wont work

vector<boost::any> v1
vector<float> v2

std::fill(v1.begin().v1.end(),v2) // This will not copy anything.
2

There are 2 best solutions below

15
On

According to this,

vector<boost::any> v1;
vector<float> v2;

v2.reserve(v1.size());
std::transform(std::begin(v1), std::end(v1), std::back_inserter(v2), 
[] (const auto& v1_val) { return boost::any_cast<float>(v1_val); });

will work.

... reserve(...) is the most important line here [ so that you don't reallocate memory when you add more and more items to the vector ].

To be honest, I don't really understand how to do it efficiently (memcpy-like), because you have a number of objects of different type, and to add it to another container, you have to cast EACH one to that type. You can't possibly do it more efficient than with a simple cycle or what other STL stuff provides (which is also a simple cycle anyway).

0
On

Your problem cannot be solved without copying. When you store some floats into a std::vector<boost::any>, those floats will be stored in memory at completely unrelated places. This is caused by the applied type eraseure technique.

Live demo: https://godbolt.org/z/a91qWazK7

You can observe that those floats have different addresses than are the addresses of any objects inside a vector. This means that the floats are not stored in the vector's buffer itself. (In theory, they could be stored in this buffer if some small buffer optimization technique would be applied by boost::any, which doesn't seem to happen. However, even then, this wouldn't help since the elements wouldn't be store contiguously in memory.)

Bottom line: If you need to get floats stored in std::vector<boost::any> to std::vector<float>, there is no way to do that without copying them.