I would like to represent a std::vector
of a structure containing several integers as a "flatten" vector of integers, without copying the data.
I tried something with a reinterpret_cast
as shown below:
#include <vector>
#include <iostream>
struct Tuple
{
int a, b, c;
};
int main()
{
// init
std::vector<Tuple> vec1(5);
for(size_t i=0; i<vec1.size(); ++i)
{
vec1[i].a = 3 * i + 0;
vec1[i].b = 3 * i + 1;
vec1[i].c = 3 * i + 2;
}
// flattening
std::vector<int>* vec2 = reinterpret_cast<std::vector<int>*>(&vec1);
// print
std::cout << "vec1 (" << vec1.size() << ") : ";
for(size_t i=0; i<vec1.size(); ++i)
{
std::cout << vec1.at(i).a << " " << vec1.at(i).b << " " << vec1.at(i).c << " ";
}
std::cout << std::endl;
std::cout << "vec2 (" << vec2->size() << ") : ";
for (size_t j = 0; j < vec2->size(); ++j)
{
std::cout << vec2->at(j) << " ";
}
std::cout << std::endl;
return 0;
}
which works well since the output is:
vec1 (5) : 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
vec2 (15) : 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
My questions are :
g++ 6.3.0
)vec2
knows that the size of the vector is 15
and not 5
?reinterpret_cast
? (If I "accidentally" add a double
member to Tuple
, the resulting issue could be hard to track...)vec1
has a specific allocator: std::vector<Tuple,A<Tuple>>
, what should be the type of vec2
? std::vector<int>
or std::vector<int,A<int>>
or std::vector<int,A<Tuple>>
? You can't legally reinterpret_cast the entire vector to a different type of vector. But you can legally cast a pointer to struct to a pointer to the first element of that struct. So this works:
std::vector<Tuple> vec1(5);
int* vec2 = &vec1.front().a;
size_t vec2_size = vec1.size() * sizeof(vec1[0]) / sizeof(vec2[0]);
for (size_t j = 0; j < vec2_size; ++j)
{
std::cout << vec2[j] << " ";
}
You need to make sure there's no padding in Tuple
, so:
static_assert(sizeof(Tuple) == 3 * sizeof(int), "Tuple must be 3 ints");
To answer your bulleted questions:
int*
.