Reputation: 650
I have a function that requires a pointer to vector of type uint16_t
. This function fills the vector with the data. I have also object that should hold the data but in form of the vector of type uint8_t
. My code looks as following:
void fill1(vector<uint16_t> *data);
void fill2(vector<uint64_t> *data);
class Object
{
uint32_t data_depth;
vector<uint8_t> data;
}
Object object1;
object1.data_depth = 16;
fill1((vector<uint16_t>*) &object1.data);
Object object2;
object2.data_depth = 64;
fill2(vector<uint64_t>*) &object2.data);
// somewhere later in the code
if (object1.data_depth == 16)
vector<uin16_t> * v = (vector<uint16_t>)(&objec1.data);
Is it the save way of pointer conversion of vector of different types?
Upvotes: 1
Views: 3972
Reputation: 19721
It is not safe. A vector is, at the fundamental level, not an array of the type, but an object containing some data, including a pointer to an array of the type. That cast you do will cause a misinterpretation of the additional data. Indeed, you are not even guaranteed that the implementation of vector
doesn't depend on the type (I doubt that this is done anywhere — with the exception of vector<bool>
which has to be implemented differently — but it is definitely allowed, as long as all individual implementations conform to the standard).
You could use boost::variant
to allow vectors of different base types to be stored in Object::data
.
Here's how your code might look like:
#include <boost/variant.hpp>
class Object
{
boost::variant<std::vector<uint16_t>, std::vector<uint64_t> > data;
};
struct fill_visitor: boost::static_visitor<>
{
template<typename T>
void operator()(std::vector<T>& v)
{
fill(&v);
}
};
// ...
boost::apply_visitor(fill_visitor(), object1.data);
Upvotes: 1
Reputation: 1145
You could probably do something like this:
template <typename T>
void fill(vector<unsigned char>& data)
{
assert(data.size() % sizeof(T) == 0);
T* pReinterpreted = reinterpret_cast<T*>(&data[0]);
size_t count = data.size() / sizeof(T);
// do some stuff with your array of reinterpreted values
}
class Object
{
uint32_t data_depth;
vector<unsigned char> data;
}
Object object;
fill<uint16_t>(object.data);
Naturally, this is unsafe code so I wouldn't do it unless you know exactly what the trade-offs are here.
Upvotes: 3