Reputation: 1268
Is there an easy way to stride through an STL vector of structures by member? In other words, if I have a struct like this:
struct foo {
double x, y, z;
};
in a vector std::vector<foo> bar(20)
, can I stride across the array picking out x from each struct?
I've tried this, but it does not seem to work:
for (int i=0; i<20; ++i)
{
double xx = (&bar[0].x + i*sizeof(bar[0]))->x;
}
Why doesn't that work? Does sizeof(bar[0])
not account for the padding between structs?
Note: I realize this is a really silly way to access x in a loop, but this loop is just an experiment to see if the stride works or not.
If it helps, I want to do this so I can pass bar to a library routine that accepts a pointer and a stride as constructor parameters to its own internal datatype. I could, of course, convert my code from AoS to SoA, but I don't want to do that unless I absolutely have to.
Upvotes: 1
Views: 427
Reputation: 24581
&bar[0].x is a pointer to double. To add the appropriate shift, you would need to cast it into char*, then double* again.
double xx = *reinterpret_cast<double*>(reinterpret_cast<char*>(&bar[0].x) + i*sizeof(bar[0]));
In anycase, you should really consider using standard algorithms for your purpose.
Upvotes: 0
Reputation: 8594
&bar[0].x
is a pointer to double. You're adding i*sizeof(bar[0])
to it.
The effect is that the address stored in the pointer increases by i*sizeof(bar[0])*sizeof(double)
which is not what you expect.
A correct expression is
&bar[0].x + i*sizeof(bar[0])/sizeof(double)
Upvotes: 1
Reputation: 490048
I think I'd compute the stride directly instead, using something like:
struct point {
double x, y, z;
};
int main() {
point points[2];
std::cout << "stride = " << (char *)(&(points[1].x)) - (char *)(&(points[0].x)) << "\n";
}
Upvotes: 1